多重背包问题,在网上看了背包九讲的前三篇,但感觉还是理解的不够透彻,过一段时间集中搞一下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;
}