//题意:给你6种不同面值的弹球,让你把它们分成两份,有一个条件是”它们不能被切开,均分的前提是,保证每个弹球的完整性“;
//思路:数据量很大,用二进制拆分来提高效率,将一个整数M拆分成1,2,4,8,2^n,M-2^n+1,这种形式,在后在合并,转化成01背包求解,
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int num[420010];
int dp[420020];
struct node
{
int value;
int m;
} Node[10000];
int max(int a,int b)
{
return a>b?a:b;
}
int main()
{
int num[7];
int sum;
int k,mm;
int count;
int ans=0;
while(1)
{
sum=0;
count=0;
for(int i=1; i<=6; i++)
{
scanf("%d",&num[i]);
sum+=num[i]*i;
}
if(sum==0)
break;
if(sum%2!=0)
{
printf("Collection #%d:\n",++ans);
printf("Can't be divided.\n\n");
continue;
}
else
{
for(int i=1; i<=6; i++) //二进制拆分。
{
k=1;
mm=num[i];
while(k<=mm)
{
Node[count].m=i;
Node[count++].value=k;
mm-=k;
k*=2;
}
Node[count].value=mm;
Node[count++].m=i;
}
int tem;
for(int i=0; i<=sum; i++)
dp[i]=0;
for(int k=0; k<count; k++)
{
tem=Node[k].value*Node[k].m;
for(int j=sum/2; j>=tem; j--)
{
dp[j]=max(dp[j],dp[j-tem]+tem);
}
}
if(dp[sum/2]==sum/2)
{
printf("Collection #%d:\n",++ans);
printf("Can be divided.\n\n");
}
else
{
printf("Collection #%d:\n",++ans);
printf("Can't be divided.\n\n");
}
}
}
return 0;
}