地址 https://www.papamelon.com/problem/217
解答
將切割逆向看,可以看做是將多段木棒粘合起來。粘合的成本是兩個木棒的長度
可以看到處於樹最底層的木棒長度在每次粘閤中都加入了進去。
所以底層的節點應該越短越好,比如5.
這就是一種貪心思想。具體原理可以參考哈夫曼樹。
由於粘合後的木棒也需要作爲木棒供下次粘合選擇,所以不僅僅是一開始將所有起始的木棒排序就好了。
我們需要配合使用堆這個數據結構來進行元素排序。
每次取兩段最短木棒粘合,然後將粘合的木棒放入選擇堆中,按照長短排序。一共n次,排序時間爲logn。 總體時間複雜度爲 O(nlogn)
#include <iostream>
#include <queue>
using namespace std;
using ll = long long;
priority_queue<ll, vector<ll>, greater<ll>> pq;
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
pq.push(x);
}
ll ret = 0;
while (pq.size() > 1) {
ll x = pq.top(); pq.pop();
ll y = pq.top(); pq.pop();
ret += x + y;
pq.push(x + y);
}
cout << ret << endl;
return 0;
}