hdu 1023 背包
简单背包,不过直接背包会超时,需要将每一种物品个数转化一下,方法是:将第i种物品分成若干件物品,其中每件物品有一个系数,这件物品的费用和价值均是原来的费用和价值乘以这个系数。使这些系数分别为 1,2,4,...,2^(k-1),n[i]-2^k+1,且k是满足n[i]-2^k+1>0的最大整数。例如,如果n[i]为13,就将这种 物品分成系数分别为1,2,4,6的四件物品。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int coin[7],res[60000],value[10000],N; int change(int a,int n) { int k=1; if(n==0) return 0; do { n-=k; value[N++]=k*a; k=k<<1; }while(n>=k); if(n>0) value[N++]=n*a; return N; } int main() { int i,j,count=0,sum; while(scanf("%d %d %d %d %d %d",&coin[1],&coin[2],&coin[3],&coin[4],&coin[5],&coin[6])) { if(coin[1]+coin[2]+coin[3]+coin[4]+coin[5]+coin[6]==0) break; sum=0; N=0; count++; for(i=1;i<=6;i++) { sum+=coin[i]*i; change(i,coin[i]); } if(sum%2==1) { printf("Collection #%d:\nCan't be divided.\n\n",count); continue; } memset(res,0,sizeof(res)); res[0]=1; for(i=0;i<N;i++) for(j=sum/2;j-value[i]>=0;j--) if(res[j-value[i]]) res[j]=1; if(res[sum/2]) printf("Collection #%d:\nCan be divided.\n\n",count); else printf("Collection #%d:\nCan't be divided.\n\n",count); } return 0; }