poj 1014

来源:互联网 发布:淘宝二手市场靠谱吗 编辑:程序博客网 时间:2024/05/16 10:10

多重背包问题,在网上看了背包九讲的前三篇,但感觉还是理解的不够透彻,过一段时间集中搞一下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;elsecout<<"Collection #"<<t<<":"<<endl<<"Can't be divided."<<endl;}cout<<endl;}return 0;}