uva 10954 add all
2016-03-17 16:26
288 查看
//维护一个堆,即优先权队列,每次取出最小的两个数 #include<iostream> using namespace std; const int maxn=5010; int a[maxn],n; void sift(int i) //以i为根的子树调整为堆 { a[0]=a[i]; int k=i<<1;//计算左儿子指针k while(k<=n) { if(k<n&&a[k]>a[k+1])//计算左右儿子中较小者的下标 k++; if(a[0]>a[k])//若k位置的值小于子根,则上移到父亲的位置,否则退出循环 { a[i]=a[k]; i=k; k=i<<1; } else k=n+1; } a[i]=a[0];//将子根值送入腾出的i位置 } void work() { for(int i=n>>1;i;i--) //建立小根堆 sift(i); long long ans=0;//结果总和 while(n!=1) { swap(a[1],a[n--]);//取出堆首的最小数(与堆尾交换,堆长减1) sift(1);//重新调整堆 a[1]+=a[n+1];//两个最小数相加,调整堆 ans+=a[1]; sift(1); } cout<<ans<<endl;//输出结果 } int main() { while(cin>>n&&n) { for(int i=1;i<=n;i++) cin>>a[i]; work(); } return 0; }
STL实现:
#include <iostream> #include<cstdio> #include<queue> using namespace std; int main() { int n,x; while (~scanf("%d",&n)&&n) { priority_queue<int,vector<int>,greater<int> >q; // 申明从小到大排序的优先权队列 for (int i=0;i<n;i++) { scanf("%d",&x); q.push(x); } int ans=0; for (int i=0;i<n-1;i++) { int a=q.top();q.pop(); int b=q.top();q.pop(); ans+=a+b; q.push(a+b); } printf("%d\n",ans); } }
相关文章推荐
- IOS-57-导致内存未释放的常见原因(现象:dealloc不执行等)
- 牛顿下山法
- BB-Black: 如何擦除emmc里的内容?
- nginx tomcat 负载均衡
- 学习之spring属性文件注入
- Java流操作之转换流
- NOSQL的学习
- 环形进度条的实现方法总结和动态时钟绘制(CSS3、SVG、Canvas)
- 机器学习实战(1)-KNN(K-近邻算法)
- long 转int
- 爬虫遇见的编码问题汇总
- 链表就地逆置
- AsyncTask源码分析
- fastjson
- 属性类:Properties
- 字典转成字符串iOS
- block循环引用情况
- linux 中FORK()函数详解
- Liferay Portal 6.2 GA6 SDK Plugin Maven开发
- U3D同步加载Assetbundle