题目:
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n;
cin>>n; //这里直接用队列就好了,没必要再存数组里
priority_queue<ll,vector<ll>,greater<ll>> pq; //类型比较简单,默认是大根堆,要的是小根堆把less直接改成greater
for(int i=1;i<=n;++i){
ll x;
cin>>x;
pq.push(x);
}
ll ans=0;
while(pq.size()>=2){
//这里pop出来两个最小的数,也就是小根堆顶部的两个数
ll x=pq.top();
pq.pop();
ll y=pq.top();
pq.pop();
ans+=x+y; //求和
pq.push(x+y); //把最小数的和push回去
}
cout<<ans<<"\n";
return 0;
}
- ### 这道题注意要开long long(int大概是2e9可能会超范围)
- ### 这里用到一点点贪心
- 1.先将1和2合并就消耗了3点体力,再将3和9合并就消耗了12点体力,共消耗15点体力
- 2.先将2和9合并就消耗了11点体力,再将1和11合并就消耗了12点体力,共消耗23点体力
- 方案1更省体力
整体思路:
- 使用优先队列小根堆,存放数据
- 取最小两数相加,多次求和
- 得到最佳消耗til