【樹的算法】之求分割木板最小開銷

#include <iostream>
#include <queue>
using namespace std;

/**
 * 原題:
 * 現需要將一塊木板切成N塊,每次切斷木板時需要的開銷爲當前木板的長度。
 * 例如要將長度爲21的木板切成5/8/8三塊木板,長21的木板切成138,開銷
 * 21,然後再將長度13的木板切成58時,開銷爲13,於是開銷合計是21+13=34
 * 現求:按題目要求將木板切割完後最小的開銷是多少
 */
#define N 3
static int L[N] = {5,8,8};

/**
 * 思路:
 * 逆向求解,即求將N塊木板合成一塊所需要的最小開銷
 * 將長度爲58的木板合成長度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



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章