首页 > 代码库 > uva--10954+贪心
uva--10954+贪心
题意:
输入n个数将它们相加。相加的时候每次只能选择2个数,然后定义这两个数的和为这一次相加的代价。
问以什么顺序相加可以使得总的代价最小。
思路:
从n个数中选2个数相加后然后问题就变成了n-1个数相加了,所以我们可以采取的一个贪心策略是每次都选
两个最小的数相加。具体实现的时候可以先对n个数排一下序,然后取前2个数相加,再将结果插入到原数组中(这是插入排序的思想,其实也可以每次都用快排排序,但那样很慢就是了。)。
后面在网上看一下别人的解题报告,发现都说是哈夫曼树的模型,可以采用优先队列解决(哈夫曼树还没看就不管了),然后就写了一个优先队列,果然快了不少。
代码如下:
<span style="font-size:18px;">#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; inline int swap(int &a,int &b) { int t; t=a; a=b; b=t; } int main() { int i,j,n,a[5500]; while(scanf("%d",&n)&&n) { for(i=0;i<n;i++) scanf("%d",&a[i]); int k=0,cost=0,sum; sort(a,a+n); while(k!=n-1) { sum=a[k]+a[k+1]; cost+=sum; ++k; a[k]=sum; for(i=k;i<n-1;i++) { if(a[i]>a[i+1]) swap(a[i],a[i+1]); else break; } } printf("%d\n",cost); } return 0; } </span>
优先队列的:
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; int main() { int i,j,n; ///声明一个小整数优先的优先队列 priority_queue<int,vector<int>,greater<int> >q; while(scanf("%d",&n)&&n) { for(i=0;i<n;i++) { int x; scanf("%d",&x); q.push(x); } int cost=0; while(n-1) { int a=q.top(); q.pop(); int b=q.top(); q.pop(); cost=cost+a+b; q.push(a+b); n--; } q.pop(); printf("%d\n",cost); } return 0; }
uva--10954+贪心
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。