题目
优先队列
思路
如果听说过“哈夫曼”这个词,那么此题的思路就很清晰了,有兴趣可以看看 ⌊ \lfloor ⌊哈夫曼树 ⌉ \rceil ⌉。
由题意可知,要使体力的消耗最小,我们应该优先选择最小数量的果子进行合并,并不是排序之后按排序顺序依次合并,而是需要始终维护所有果子的数量最小值,这就不得不让人想起一个叫 “堆” 的数据结构,这种数据结构可以完美地适合这道题,具体见代码。
代码
#include <iostream>
#include <queue>
using namespace std;
int main(void) {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n = 0, a = 0, b = 0, ans = 0;
cin >> n;
// 将优先队列的排序方式定为从小到大
priority_queue<int, vector<int>, greater<int>> pq;
// 将输入的数据放入优先队列
while (n--) {
cin >> a;
pq.emplace(a);
}
// 不停地取出堆顶的两个最小的数相加
while (pq.size() > 1) {
a = pq.top();
pq.pop();
b = pq.top();
pq.pop();
// 并累加结果
ans += a + b;
pq.emplace(a + b);
}
// 最后输出结果
cout << ans << endl;
return 0;
}