小根堆实在是太实用了
合并果子大体思路:
每次将最小的两堆果子合并
我们每次将某两堆果子合并在一起,而且每次合并的时候,体力的消耗是两堆果子的总和,而且每堆果子都逃不过被合并的命运。
越是合并的早的果子,被合并的次数越多,所以我们要尽可能地让体力消耗值小的果子先合并
而我们的小根堆可以很好的解决这个问题,以为小根堆的根永远是这个堆里的最小值。
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
int n;
int main(){
cin >> n;
priority_queue<int, vector<int>, greater<int>> heap;
while (n -- ){
int x;
cin >> x;
heap.push(x);
}
int res = 0;
while (heap.size() > 1){//合并到最后还剩下一堆,这个时候,是不用合并的
int x = heap.top(); heap.pop();//找到最小的堆,我们将他和另一个果子堆结合,他就不复存在了,所以pop
int y = heap.top(); heap.pop();//找到最小的堆,我们将他和另一个果子堆结合,他就不复存在了,所以pop
res += x + y;//找到两个最小的果子堆
heap.push(x + y);//将合并后的果子堆放入小根堆里
}
cout << res << endl;
return 0;
}