题目描述
在一片沙滩上摆放着n堆石子。 现要将石子有次序地合并成一堆。 每次任选2堆石子合并成新的一堆,合并的费用为新的一堆石子数。试设计一个算法,计算出将n堆石子合并成一堆的最小总费用。
输入
输入数据第1行有1个正整数 n(1≤n≤100000),表示有 n堆石子,每次选2堆石子合并。第2行有 n个整数, 分别表示每堆石子的个数(每堆石子的取值范围为[1,1000]) 。
输出
数据输出为一行, 表示对应输入的最小总费用。
样例输入
7
45 13 12 16 9 5 22
样例输出
313
122
/ \
75 47
/ \ / \
30 45 22 25
/ \ / \
14 16 12 13
/ \
5 9
14+30+75+122+47+25=313.
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
using namespace std;
int main(void)
{
//从小到大排序的优先队列
priority_queue<int,vector<int>,greater<int> >q;
int n,t;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&t);
q.push(t);
}
long long sum=0,s=0;//注意结果的数据类型
while(q.size()>1){//栈中剩最后一个停止
s=0;
s+=q.top(); //把最轻的加上,再删除掉
q.pop();
s+=q.top(); //再加上第二轻的,之后删掉
q.pop();
q.push(s); //将新生成的堆入队,入队后再次从小到大排序
sum+=s; //计算合并两堆花费的成本
}
printf("%lld",sum);
}
【注】优先队列(priority_queue)和queue不同的就在于可自定义其中数据的优先级, 让优先级高的排在队列前面,优先出队。优先队列具有队列的所有特性,包括基本操作,只是在这基础上添加了内部的一个排序,它本质是一个堆实现。
1.头文件#include<queue>
2.对于基础类型,默认是大顶堆
priority_queue<int> a;
等同于 priority_queue<int, vector<int>, less<int> > a;
小顶堆
priority_queue<int, vector<int>, greater<int> > b;