同HDU 1059 细节见这里
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define MAX_N 210005 //最多20000件
int marblenum[7], marblevalue[7]={0,1,2,3,4,5,6},
dp[MAX_N+1], a[200];
int main()
{
int testnum = 0;
while(scanf("%d%d%d%d%d%d",&marblenum[1],&marblenum[2],&marblenum[3],&marblenum[4],&marblenum[5],&marblenum[6]))
{
int flag = 0, sum = 0;
for(int i = 1;i < 7;i++)
{
if(marblenum[i]!=0)
{
flag = 1;
sum += marblenum[i] * i;
}
}
if(flag)
{
testnum++;
if(sum % 2 != 0)
{
printf("Collection #%d:\nCan't be divided.",testnum);
}
else //可以整除的情况
{
int contain = sum / 2,cnt = 0;
for(int i = 1;i <= 6;i++)//遍历每一种
{
//按规律分堆
for(int j = 1;j <= marblenum[i];j *= 2)//n+1>2^k 2^j <= n 相当于 2^j < n+1
{
a[++cnt] = i*j; //生成的这一堆的价值
marblenum[i] -= j; //用掉多少就减去多少
}
if(marblenum[i] != 0) //没有完全用光
a[++cnt] = i*marblenum[i]; //额外放一堆
}
memset(dp, 0, sizeof(dp));
//此时转化为01背包 已经拥有cnt种物品 每件一个 最大容量contain
for(int i = 1;i <= cnt;i++)
{
for(int j = contain;j >= a[i];j--)
{
dp[j] = max(dp[j],dp[j-a[i]]+a[i]);
}
}
if(dp[contain]!=contain)
{
printf("Collection #%d:\nCan't be divided.", testnum);
}
else
{
printf("Collection #%d:\nCan be divided.", testnum);
}
}
printf("\n\n");
}
else //全部为0 结束输入
{
break;
}
}
return 0;
}