papamelon 217. 柵欄修理 Fence Repair(挑戰程序設計競賽)

地址 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;
}

我的視頻題解空間

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