多重背包问题,在网上看了背包九讲的前三篇,但感觉还是理解的不够透彻,过一段时间集中搞一下dp,现在就当预习啦
#include <iostream> #include <cmath> using namespace std; int f[20001*6],m[7]; int main() { int t=0; while(cin>>m[1]>>m[2]>>m[3]>>m[4]>>m[5]>>m[6]) { t++; int i,sum=0; for(i=1;i<=6;i++) { sum+=m[i]*i; } if(sum==0) break; if(sum%2==1) cout<<"Collection #"<<t<<":"<<endl<<"Can't be divided."<<endl; else { int cap=sum/2; memset(f,0,sizeof(f)); int v; for(i=1;i<=6;i++) { if(m[i]==0) continue; if(m[i]*i>cap)//等价于此背包可以无限使用,即完全背包 { for(v=i;v<=cap;v++) f[v]=f[v]>(f[v-i]+i)?f[v]:(f[v-i]+i); } else { int amount=0,k=1; while((2*k-1)<m[i]) { for(v=cap;v>=k*i;v--) f[v]=f[v]>(f[v-i*k]+i*k)?f[v]:(f[v-i*k]+i*k); amount+=k; k*=2; } for(v=cap;v>=i*(m[i]-amount);v--) f[v]=f[v]>(f[v-i*(m[i]-amount)]+i*(m[i]-amount))?f[v]:(f[v-i*(m[i]-amount)]+i*(m[i]-amount)); } } if(f[cap]==cap) cout<<"Collection #"<<t<<":"<<endl<<"Can be divided."<<endl; else cout<<"Collection #"<<t<<":"<<endl<<"Can't be divided."<<endl; } cout<<endl; } return 0; }