题目
https://vjudge.net/problem/POJ-3253
锯木头,切割一块长度为21的木板,费用为21美分,给n块木头和其长度,求最小的金额
分析
倒过来看,就是每一次相加时,都是最小的两个数相加,这样可保证总和最小
代码
#include <iostream>
#include <queue>
using namespace std;
int main() {
int n;
while(cin>>n)
{
priority_queue<int,vector<int>,greater<int>> pq;
while(n--)
{
int x;
cin>>x;
pq.push(x);
}
long long int sum=0; //sum要为lli,不然会wa
if(pq.size()==1) //因为是两个数字相加,要考虑只有一个数字的情况
{
int t = pq.top();
sum+=t;
pq.pop();
}
while(pq.size()>1)
{
int t = pq.top();
pq.pop();
int q = pq.top();
pq.pop();
int s = t+q;
sum+=s;
pq.push(s);
}
cout<<sum<<endl;
}
return 0;
}
注意
题目中给的数据比较大,最坏会超过10位,所以sum要用
l
l
i
lli
lli,也有用哈夫曼树做的,会超时,原理都差不多~