题目链接: 甄总搬石头
题目来源: 牛客网
题目描述
现在草地上有n堆石头,甄总想要合并这n堆石头成为1堆,但是他每次能力有限,所以只能一次合并2堆石头至1堆。
现在已知第i堆石头有ai块,假设甄总要合并第i堆和第j堆石头,则需要花费ai+aj的力气。
给出n堆石头每堆石头的个数,求出甄总要合并n堆成1堆石头一共需要多少力气。
输入
第1行输入一个整数n,代表一共有n堆石头。
第2行输入n个整数ai,表示第i堆有ai块石头。
输出
输出一行整数,表示一共需要多少力气。
样例输入
样例一:
3
1 2 3
样例二:
5
2 3 4 4 7
样例输出
样例一:
9
样例二:
45
参考代码:
#include <iostream>
#include <queue>
using namespace std;
priority_queue <int, vector<int>, greater<int> > q;
// 定义一个升序优先队列 q
// 注:“greater<int>” 与 “>” 中间有个空格 不可删
int main()
{
int n;
cin >> n;
while(n--) {
int num;
cin >> num;
q.push(num); // 将n堆石头的块数放入队列
}
int ans=0;
while(q.size() > 1) {
// 在石头只剩 一堆 时结束搬运
int a = q.top();
q.pop();
int b = q.top();
q.pop();
// 取队列的前两个 将它们堆在一起
int sum = a+b;
// 合并两堆石块需消耗的力气
q.push(sum);
ans += sum;
// 消耗的总力气
}
cout << ans << endl;
return 0;
}
优先队列的基本操作:
- top 访问队头元素
- empty 队列是否为空
- size 返回队列内元素个数
- push 插入元素到队尾 (并排序)
- emplace 原地构造一个元素并插入队列
- pop 弹出队头元素
- swap 交换内容
总结:
- 数据并不是特别大,给所需的总力气定义为int类型可以过题;
- 考虑到时间复杂度,用数组一直sort()排序会超时。