题意:两个人一起收集了有价值为1、2、3、4、5、6的宝石,数量分别为n1,n2...n6,求他们是否能分配宝石使两个人获得的宝石总价值相等。
思路:在知道了要进行二进制转换之后,我先对不同价值的宝石进行了二进制转换,再处理01背包问题,结果还是TLE,看了网上的题解,对比之后发现还需要在每次对一种价值宝石进行二进制转换的同时进行01背包的求解。
#include
#include
int ans[120000];
int main()
{
#ifdef LOCAL
freopen("data.in", "r", stdin);
#endif
int n[10] ,cur, sum, t = 0, count, val;
while(scanf("%d%d%d%d%d%d", &n[1], &n[2], &n[3], &n[4], &n[5], &n[6]) != EOF)
{
if( !(n[1] || n[2] || n[3] || n[4] || n[5] || n[6])) break;
t++;
printf("Collection #%d:\n", t);
sum = 0;
for(int i = 1; i <= 6; i++)
sum += n[i] * i;
if(sum % 2 != 0)//总价值为奇数
{
printf("Can't be divided.\n\n");
continue;
}
else//总价值为偶数
{
count = 0;
sum /= 2;
for(int i = 0; i <= sum; i++)
ans[i] = 0;
for(int i = 1; i <= 6; i++)
{
for(int j = 1; j <= n[i]; j *= 2)
{//二进制转化
val = j * i;
n[i] -= j;
for(int k = sum; k >= val; k--)
{//01背包处理
cur = ans[k - val] + val;
if(cur > ans[k])
ans[k] = cur;
}
}
if(n[i])
{
val = n[i] * i;
for(int k = sum; k >= val; k--)
{
cur = ans[k - val] + val;
if(cur > ans[k])
ans[k] = cur;
}
}
}
if(ans[sum] == sum) printf("Can be divided.\n\n");
else printf("Can't be divided.\n\n");
}
}
return 0;
}