暑假- 动态规划 I-(T - Dividing)
2015-07-22 20:44
309 查看
/* 本题与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; }
相关文章推荐
- 数据库之视图、索引
- CAVLC中的前缀和后缀
- scrapy模拟登录微博
- Android 属性系统 Property service 设定分析
- 南阳 oj NYoj 贪心 题目915 +-字符串
- Android实战简易教程-第二十二枪(基于Baas的用户注册功能)
- scrapy模拟登录微博
- C#遍历系统所安装的打印机,使用WMI方式获取打印机的所有属性
- 1、文件ZIp的对byte[]的压缩和解压缩
- HDU 4082 Hou Yi's secret-求相似三角形的最大个数-(坑货)
- postgres修改使用密码登录的方法
- 南阳oj NYOJ 贪心 找点 题目891
- 关于fone的安装
- 多校1 Assignment(枚举 二分 rmq) 1002
- 浏览器的工作机制
- linux中软件包管理
- 最短路径算法
- [Leetcode]-Unique Paths II
- 特殊文件: /dev/null和/dev/tty
- linux中软件包管理