nyoj DivideingJewels(多重背包)
来源:互联网 发布:怎么安装电视直播软件 编辑:程序博客网 时间:2024/06/03 10:15
DivideingJewels
原题链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=546
方法一:
转换成01背包问题,防止超时要进行一些必要的剪枝和二进制优化
代码:
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int v[100010],dp[100010];int main(){ int m=1,i; while(1) { memset(dp,0,sizeof(dp)); int a[15],sum=0,j,k=0; for(i=1; i<=10; i++) { scanf("%d",&a[i]); sum+=a[i]*i; } if(!sum) break; if(sum&1) printf("#%d:Can't be divided.\n\n",m++); else { for(i=1; i<=10; i++) { for(j=1; j<=a[i]; j<<=1)//二进制优化,相当于把重量相同的n件物品转换成不同重量的有且只有1件的物品,即转换成01背包。例:13可以分为 1(2^0)、2(2^1)、4(2^2)、6,因为1、2、4、6这四个数可以组合成1—13中的所有数字) { v[k++]=i*j; a[i]-=j; } if(a[i]>0) { v[k++]=a[i]*i; } } sum>>=1; for(i=0; i<k; i++) for(j=sum; j>=v[i]; j--) dp[j]=max(dp[j],dp[j-v[i]]+v[i]); if(dp[sum]==sum) printf("#%d:Can be divided.\n\n",m++); else printf("#%d:Can't be divided.\n\n",m++); } } return 0;}
方法二:
对于多重背包,可以先对每种物品判断是否超出背包容量,1.如果该种物品超出,则可以当做完全背包来做,因为完全背包不就是装满该容量的背包,物品可以任意取嘛,都一样的。2.如果没有超出,则对于该种物品来说,当做01背包来做,但是这里将该种物品又进行了捆绑分组(2进制优化,时间复杂度可降到O(V*Σlog(n[i])))
代码:
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int dp[100010];int sum,j;void zeroonepack(int c,int w){ for(j=sum;j>=c;j--) dp[j]=max(dp[j],dp[j-c]+w);}void complatepack(int c,int w){ for(j=c;j<=sum;j++) dp[j]=max(dp[j],dp[j-c]+w);}void multipiepack(int c,int w,int n){ if(c*n>=sum) complatepack(c,w); else { int k=1; while(k<n) { zeroonepack(c*k,w*k); k<<=1; n-=k; } if(n>0) zeroonepack(c*n,w*n); }}int main(){ int m=1,i; while(1) { memset(dp,0,sizeof(dp)); int a[12]; sum=0; for(i=1;i<=10;i++) { scanf("%d",&a[i]); sum+=a[i]*i; } if(!sum) break; if(sum&1) printf("#%d:Can't be divided.\n\n",m++); else { sum>>=1; for(i=1;i<=10;i++) multipiepack(i,i,a[i]); if(dp[sum]==sum) printf("#%d:Can be divided.\n\n",m++); else printf("#%d:Can't be divided.\n\n",m++); } } return 0;}ps:多重背包模板题。。
1 0
- nyoj DivideingJewels(多重背包)
- DivideingJewels
- NYOJ 546 Divideing Jewels 多重背包
- NYOJ 546 Divideing Jewels 多重背包
- (背包三)多重背包
- hdu2191(多重背包)
- Coins(多重背包)
- Dividing ( 多重背包)
- hdu1171(多重背包)
- SDUT3131(多重背包)
- POJ_1276_ZOJ_1366_CashMachine(多重背包)
- hdu2191(多重背包)
- HDOJ2191(多重背包)
- poj1276(多重背包)
- POJ_2392_SpaceElevator(多重背包)
- HDU2191(多重背包)
- 多重背包(HDU2191)
- Dividing(多重背包)
- 戏说设计模式(二)适配器模式
- 关于php中一些字符串的一些面试题的总结
- Tr A 矩阵快速幂
- 新浪PHP工程师笔试题
- Java Web基础——Action+Service +Dao三层的功能划分
- nyoj DivideingJewels(多重背包)
- 百度php工程师面试题
- Smbclient介绍
- JavaScript原型
- DXF-TEXT 说明
- 还得PHP啊
- ROS 不能再详细的安装教程
- 【3】Struts2的Action访问
- Java:类中代码的执行顺序