您的位置:首页 > 其它

codevs1063合并果子

2017-09-26 00:28 363 查看
这个题感觉应该算是个贪心

每次合并重量最小的两堆果子

我不知道我下面这样证明对不对- -我没有学过数学归纳法什么的

假设有三堆果子,a1 a2 a3
那么消耗体力有三种情况
a1+a2 + a1+a2+a3
a1+a3 + a1+a2+a3
a2+a3 + a1+a2+a3
显然
第二次合并果子消耗的体力都是相同的
所以应该在第一次合并的时候消耗最少的体力
即第一次合并应该选择min(a1+a2,a1+a3,a2+a3)
每次合并完之后把合并出来的一个新果子堆冒泡冒上去就可以了
不过应该也可以用大根堆
这样的话复杂度应该主要就是冒泡排序贡献的了
大概最坏是O(n^2)


代码如下

#include <iostream>
#include <algorithm>
using namespace std;
int w[10001],n;
void chang(int x,int y)
{
w[x]^=w[y];
w[y]^=w[x];
w[x]^=w[y];
}
void bub(int f)
{
for(int i=f;i<n;++i)
{
if(w[i]>w[i+1])chang(i,i+1);
else return;
}
}
bool cmp(int x,int y)
{
return x<y?1:0;
}
int main()
{
int ans=0;
cin>>n;
for(int i=1;i<=n;++i)
cin>>w[i];
sort(w+1,w+n+1);
//for(int i=1;i<=n;++i)//test
//cout<<w[i]<<' ';//test
//cout<<'\n';//test
for(int i=1;i<n;++i)
{
//cout<<i<<" "<<w[i]<<' '<<w[i+1];//
w[i+1]+=w[i];
w[i]=0;
//cout<<' '<<w[i]<<' '<<w[i+1];//
ans+=w[i+1];
//cout<<' '<<ans<<'\n';//
bub(i+1);
}
cout<<ans;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: