概述:有六種物品,每種物品對應的價值爲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;
}