暑假- 动态规划 I-(T - Dividing)

来源:互联网 发布:ps cs5 mac版破解补丁 编辑:程序博客网 时间:2024/06/05 07:50
/*本题与N - Coins相似。把6种大理石看成6种硬币。判断能否由这个硬币凑成总和的一半[平均分为2份]多重背包:转换成01背包和完全背包*/#include<iostream>#include<algorithm>using namespace std;int marbles[8];int dp[220000];//因为只有6种大理石,每种数目最多为20000,则总为(1+2+3+4+5+6)*20000               //再除以2就是dp数组的最大值。int mymax(int a,int b){return a>b?a:b;}void CompletePack(int v,int m){for(int i=v;i<=m;i++){dp[i]=mymax(dp[i],dp[i-v]+v);}}void ZeroOnePack(int v,int m){for(int i=m;i>=v;i--){dp[i]=mymax(dp[i],dp[i-v]+v);}}void MuiltPack(int v,int c,int m){if(v*c>=m){CompletePack(v,m);}else{int k=1;while(c-k>=0){ZeroOnePack(v*k,m);c-=k;k*=2;}ZeroOnePack(v*c,m);}}int main(){int ans=0;while(1){ans++;int sum=0;memset(marbles,0,sizeof(marbles));memset(dp,0,sizeof(dp));for(int i=1;i<=6;i++){cin>>marbles[i];sum+=marbles[i]*i;//sum记录总价子}if(!(marbles[1]||marbles[2]||marbles[3]||marbles[4]||marbles[5]||marbles[6])){   //结束条件break;}if(sum%2!=0)//如果不能平分。{cout<<"Collection #"<<ans<<":"<<endl;cout<<"Can't be divided."<<endl;cout<<endl;continue;}sum=sum/2;for(int i=1;i<=6;i++){if(!marbles[i])//面值为i的硬币数量为0。{continue;}MuiltPack(i,marbles[i],sum);}if(dp[sum]==sum)//如果可以由这些硬币凑成总价值的一半。{cout<<"Collection #"<<ans<<":"<<endl;cout<<"Can be divided."<<endl;cout<<endl;}else{cout<<"Collection #"<<ans<<":"<<endl;cout<<"Can't be divided."<<endl;cout<<endl;}}return 0;}

0 0
原创粉丝点击