UVa 10954 - Add All

链接:

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1895

 

题意:

有n(n≤5000)个数的集合S,每次可以从S中删除两个数,然后把它们的和放回集合,直到剩下一个数。
每次操作的开销等于删除的两个数之和,求最小总开销。所有数均小于1e5。

 

分析:

用一个优先队列代表集合S,每次从中取出两个最小的数相加,再把这两个数的和放回S中即可。
与 Huffman 编码的建立过程类似。

 

代码:

 1 #include <cstdio>
 2 #include <queue>
 3 using namespace std;
 4 
 5 int main(){
 6     int n;
 7     while(scanf("%d", &n) && n){
 8         priority_queue<int, vector<int>, greater<int> > Q;
 9         for(int x, i = 0; i < n; i++){
10             scanf("%d", &x);
11             Q.push(x);
12         }
13         int ans = 0;
14         while(Q.size() > 1){
15             int a = Q.top();  Q.pop();
16             int b = Q.top();  Q.pop();
17             ans += a + b;
18             Q.push(a + b);
19         }
20         printf("%d\n", ans);
21     }
22     return 0;
23 }

 

转载于:https://www.cnblogs.com/hkxy125/p/8137288.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值