演算法設計與分析 第七周 IPO

2021-08-29 02:24:15 字數 3229 閱讀 6419

4**與改進

第二版4.3第三版

4.4bug版

5源**

學習了貪心演算法,隨機選擇了一道題目。

貪心演算法的本質即是:每一步都選擇當前最好的點,不一定能夠得到全域性最優解,但一定要得到區域性最優解。結合這道題來考慮,按照貪心演算法的思路,在當前步,我算要考慮的就是我手中所能投資的專案中獲利最大的。有了思路,操作起來就非常簡單了。按照我們的思路,在每一步,我們都要先找到所有能夠資助的專案,並維護乙個獲利最大的專案。

演算法總結如下:

初始化乙個最大利潤max_pro = 0;該專案代號max_cap = -1;

遍歷所有專案:

for (int i = 0; i < k; i++) 

}//沒有好的投資專案

if (max_pos == -1)

//已投資過專案無法再次獲利

pro[max_pos] = 0;

//增加本金

w += max_pro;

}return w;

結果如下:

我們發現,結果超時了,分析原因:

當我們選最佳方案的時候,每選一次就要遍歷全部陣列,仔細算來,需要50000 * 50000次查詢,當然要超時。思考有什麼方法能夠減少時間呢?

實際上,是否需要遍歷所有的陣列嗎?是不需要的,考慮:如果專案需要的投資比自己所有的本金要大的話,還需要比較嗎?當然不需要,因此,我們需要乙個有序陣列,這樣遇到比本金要大的專案的時候,就不需要繼續查詢後面的元素了。

我們需要的是:先進行一邊排序,為了更快,選取快速排序,直接上**,就不解釋排序原理了

我們更改**:

//快速排序

void quicksort(int s, int t, int l, int r)

while(i < j && s[i]< x) // 從左向右找第乙個大於等於x的數

i++;

if(i < j)

} s[i] = x;

t[i] = y;

quicksort(s, t, l, i - 1); // 遞迴呼叫

quicksort(s, t, i + 1, r);

} }

quicksort(cap, pro, 0, size - 1);
需要更改判斷條件,此時只要投資金額超過本金,就不需要繼續了。

//遍歷能夠投資的所有專案

思考為什麼還會超時,結果是顯而易見的,首先,排序需要很多時間;其次,即使我們排好序,能起到多少效果:考慮,在例子中,專案本金是有序數列0, 1, 2, ..., 49999,實際上,我們一開始得到的本金就可以資助所有專案了。

因此,排序是行不通的。

我們考慮還有什麼方法能夠減少每一次的訪問次數?無非就是訪問過的不再訪問。有乙個很好的策略:我們將整個陣列分成兩段,一段是已經投資過的專案,一段是沒有投資過的專案,如圖:

每次,我們只需要維護乙個k,當有專案需要投資的時候,就把它加入已經投資過的專案那一段,並將k向後移動,這樣,就能夠保證每次訪問從k開始即可。

因此,我們不需要耗費大量時間排序。

//k,記錄開始遍歷的點

int start = 0;

for (int i = 0; i < k; i++)

}//沒有好的專案投資

if (max_pos == -1)

//將投資過的專案加入已投資佇列

話不多說,直接上**,懂的自然懂。

//bug,輕易請不要使用

// if (k == size && k == 50000)

for (int i = 0; p != profits.end(); p++, c++, i++)

//k,記錄開始遍歷的點

int start = 0;

for (int i = 0; i < k; i++)

}//沒有好的專案投資

if (max_pos == -1)

//將投資過的專案加入已投資佇列

cap[max_pos] = cap[start];

pro[max_pos] = pro[start];

start++;

w += max_pro;

}return w;}};

演算法設計與應用基礎 第七周

intersection of two arrays ii given two arrays,write a function to compute their intersection.example given nums1 1,2,2,1 nums2 2,2 return 2,2 note th...

程式設計與演算法(三)第七周 作業

027 簡單的sumarray include include using namespace std template t sumarray t a,t b return sum int main cout sumarray array,array 4 endl cout sumarray a,a...

演算法設計與分析(七) Graph And Tree

example 1 input 1,2 2,3 3,4 1,3 output 1example 2 input 1,2 1,2 1,2 output 2example 3 input 1,2 2,3 output 0本題要將一堆區間中的某些區間去掉,使得剩下的區間中沒有重疊的部分。而且要求找到最優的...