#include <iostream> #include <queue> using namespace std; /** * 原題: * 現需要將一塊木板切成N塊,每次切斷木板時需要的開銷爲當前木板的長度。 * 例如要將長度爲21的木板切成5/8/8三塊木板,長21的木板切成13和8時,開銷 * 爲21,然後再將長度13的木板切成5和8時,開銷爲13,於是開銷合計是21+13=34。 * 現求:按題目要求將木板切割完後最小的開銷是多少 */ #define N 3 static int L[N] = {5,8,8}; /** * 思路: * 逆向求解,即求將N塊木板合成一塊所需要的最小開銷 * 將長度爲5和8的木板合成長度13的木板,,開銷爲13,然後將長度13的木板與長度8的木板 * 進行合成長度爲21的木板,開銷爲21。合計開銷爲34。 * 顯然,每次將最小的兩塊木板合成時的消耗都是最小的,因此此題可用貪心算法求解 * 下面用優先隊列實現貪心算法,時間複雜度爲O(NlogN) */ int solve(){ int min = 0; //最小開銷 //聲明一個從小到大取出數值的優先隊列 priority_queue<int, vector<int>, greater<int>> que; for (int i = 0; i < N; ++i) { que.push(L[i]); } int l1, l2; //不斷選取最短的兩塊木板進行合成,合到只剩1塊爲止 while (que.size() > 1){ l1 = que.top(); que.pop(); l2 = que.top(); que.pop(); min += l1+l2; que.push(l1 + l2); } return min; } int main() { std::cout << solve() << std::endl; return 0; }
運行結果:
34