#include<iostream>
#include<string.h>
using namespace std;
int main()
{
int a[7];
int b[100];
int count=0;
while(true)
{
memset(b,0,sizeof(b));
memset(a,0,sizeof(a));
count ++;
int sum = 0;
for(int i=1; i<=6; i++)
{
cin>>a[i];
//数据预处理
if(a[i]!=0&&a[i]%6==0)
a[i]=6;
else
a[i]=a[i]%6;
sum+=a[i]*i;
}
if(sum == 0)
break;
if(sum %2)
{
printf("Collection #%d:\n",count);
printf("Can't be divided.\n\n");
continue;
}
int k = 0;
//将多重背包利用二进制优化转换成01背包问题
for(int i = 1;i<=6;i++)//依次处理1到6号石头
{
int t = 1;//权重表示2的次方 每次放的个数1 2 4 8 16 32
while(t<=a[i])
{
b[++k] = t * i;
a[i] -= t;
t *=2;
}
if(a[i] > 0)
{
b[++k] = a[i] * i;
}
}
//01背包问题
int dp[60000];
memset(dp,0,sizeof(dp));
dp[0] = 1;
for(int i = 0;i<k;i++)
{
for(int j=sum/2;j>=b[i];j--)
{
if(dp[j-b[i]])dp[j] = 1;
}
}
printf("Collection #%d:\n",count);
if(dp[sum/2]) printf("Can be divided.\n\n");
else printf("Can't be divided.\n\n");
}
system("pause");
return 0;
}
ZOJ1149-Dividing
最新推荐文章于 2025-06-02 20:51:47 发布