您的位置:首页 > 其它

CODEVS 1063合并果子

2016-11-09 11:13 218 查看
#include<cstdio>
#include<algorithm>
using namespace std;
int n,a[10010],sum;
int main(){
freopen("1063.in","r",stdin);
freopen("1063.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
sort(a+1,a+n+1);
for(int i=2;i<=n;i++){//从最小的开始合并
a[i]=a[i]+a[i-1];
sum+=a[i];
for(int j=i+1;j<=n;j++){//保证合并后 任然按照从小到大排序!!!
if(a[j-1]>a[j]){
int k=a[j];
a[j]=a[j-1];
a[j-1]=k;
}
}
}
printf("%d",sum);
return 0;
}


注意:1048石子归并 与 1063合并果子(本题)的不同

合并果子 只要求n堆进行合并 “多多可以把任意两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。”

而石子归并是在区间上相邻的2堆石子合并。”合并相邻的两堆石子”

请注意这2句话的细微差别。这2道题的题意就完全不同。

为什么石子归并必须要用区间DP呢?因为局部最优解不一定是全局最优解。所以我们不能直接贪心。

下面给出优先队列的优化,也是比较基本的优先队列练习。

//优先队列
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
#include <cstring>
using namespace std;
int n,x,ans = 0;
priority_queue<int,vector<int>,greater<int> >q;//最小值优先
int main() {
scanf("%d",&n);
for(int i = 1; i <= n; i ++) {
scanf("%d",&x);
q.push(x);
}
while(q.size() != 1) {
int u = q.top();
q.pop();
int w = q.top();
q.pop();
int z  = u + w;
ans += z;
q.push(z);
}
printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: