#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int inf= 1<<30;
const int M=330000;
int a[7],val[M],vol[M],dp[M];
int main()
{
int cas=0;
while(1)
{
cas++;
long sum=0;
for(int i=1;i<=6;i++)
{
scanf("%d",&a[i]);
sum=sum+i*a[i];
}
if(sum==0) break;
cout<<"Collection #"<<cas<<':'<<endl;
if(sum%2) // 奇数肯定不能被平分
{
cout<<"Can't be divided."<<endl<<endl;
continue;
}
// 前i种物品能否装满体积Val/2的背包;
int num=1;
for(int i=1;i<=6;i++) // 每种物品数量有限 二进制拆分
{
for(int k=1;k<=a[i];k*=2)
{
val[num]=i*k;
vol[num++]=i*k; //
a[i]-=k;
}
if(a[i]>0)
{
val[num]=a[i]*i;
vol[num++]=a[i]*i;
}
}
for(int j=0;j<=sum/2;j++) // 前0件装进体积为j所得的价值
{
if(j==0)
dp[j]=0;
else
dp[j]=-inf; // 装不满设为负
}
int flag=0;
for(int i=1;i<num;i++) // i<num 不小心取了个等号 WA了无数次!!!
{
for(int j=sum/2;j>=vol[i];j--)
{
dp[j]=max(dp[j],dp[j-vol[i]]+val[i]);
}
}
if(dp[sum/2]>=0)
{
cout<<"Can be divided."<<endl<<endl;
continue;
}
else
cout<<"Can't be divided."<<endl;
cout<<endl;
}
return 0;
}
poj 1014 多重背包入门
最新推荐文章于 2022-07-31 13:30:41 发布