概述:有六种物品,每种物品对应的价值为1~6,给定每种物品的个数,切不可分割,问能否把这堆物品分为等价值的两份。
思路:多重背包,计算过程比较复杂,所以要优化一下,先把总价值为奇数的组排除掉(因为奇数不可能分为等价值的两份),然后再套模板计算即可。
感想:无。
#include <iostream>
#include <cstring>
using namespace std;
int map[7];
int dp[100000];
int main()
{
int flag=1;
while(1)
{
int sum=0,v,cnt;
for(int i=1;i<=6;++i)
{
cin>>map[i];
sum+=i*map[i];
}
if(sum==0) break;
cout<<"Collection #"<<flag++<<":\n";
if(sum%2)
{
cout<<"Can't be divided.\n\n";
continue;
}
v=sum/2;
memset(dp,0,sizeof(dp));
dp[0]=1;
for(int i=1;i<=6;++i)
{
if(!map[i])
continue;
for(int j = 1;j<=map[i];j*=2)
{
cnt = j*i;
for(int k = v;k>=cnt;k--)
{
if(dp[k-cnt])
dp[k] = 1;
}
map[i]-=j;
}
cnt = map[i]*i;
if(cnt)
{
for(int k = v;k>=cnt;k--)
{
if(dp[k-cnt])
dp[k] = 1;
}
}
}
if(dp[v])
cout<<"Can be divided.\n\n";
else
cout<<"Can't be divided.\n\n";
}
return 0;
}