目录
题目
思路
首先,这道题有一个很明显的贪心
就是每次取最两个最小值
比如
1 2 9
则先把 1 和 2 合在一起,代价为 3,再取 3 和 9 合一起,代价为 12,最后把 3 和 12 加起来就是正确答案 15 了
想证明很简单:最小加次小一定比其他组合都小,这样每次代价就最小了
但还有一个问题,就是每次取最小和次小,再把他们的和送回去,然后再排一趟序,很容易就超时吧
所以我们就要用到优先队列 priority_queue 了
这个东西是可以自动排序的 STL大法好
它是由堆实现的,默认是大根堆,所以队首是最大值,我们就需要把他调成最小值
怎么调呢,看这里:priority_queue <int, vector<int>, greater<int> > pq;(如果你想要大根堆,就可以省略后两个参数了)
如果你在考场上忘了 greater 怎么拼,告诉你一个绝妙方法:比如压 a 的时候就压 -a 这样最大值就变成了最小值(比如 1 2 3 ,最大值为 3,如果压 -3 ,他就变成了最小值,而最大值就变成了 -1)取的时候就也用它的相反数就行了
这样每次取队首两个数,把他们加起来再压回去就行了
(具体请参考下方代码)
代码
#include <iostream> // 输入输出流头文件
#include <queue> // 优先队列需要的头文件
#include <vector> // 优先队列的第二个参数动态数组 vector 的头文件
using namespace std;
priority_queue <int, vector<int>, greater<int> > pq; // 维护一个小根堆
int n, a, ans;
int main() {
cin >> n;
for(int i = 1; i <= n; ++i) {
cin >> a;
pq.push(a); // 输入到小根堆里
}
while(pq.size() > 1) { // 只剩一堆的时候就结束
int x, y;
x = pq.top(); // 取出队首两个元素
pq.pop();
y = pq.top();
pq.pop();
ans += x + y; // 相加压回去并更新答案
pq.push(x + y);
}
cout << ans << endl; // 输出答案
return 0;
}
尾声
如果这篇题解对您(或您的团队)有帮助的话,就帮忙点个赞,加个关注!
最后,祝您(或您的团队)在 OI 的路上一路顺风!!!
┬┴┬┴┤・ω・)ノ Bye~Bye~