这个题目首先应该判断综合是否为偶数,如果不为偶数则不可分,如果为偶数则做进一步的分析。这是一道和背包有关的问题,由于是多重背包,所以需要进行转化,因为本题的数据量交大,所以不可以采用单个划分的形式,应该采用二进制划分,比如13可以分为1、2、4、6四个背包,这四个数字可以组成1-13中的任何数字。具体的做法请参考下面的代码:
#include <iostream>
#include <stdio.h>
#include <memory.h>
using namespace std;
const int N = 6;
int V, total, sum;
int bag[120005];
int w[15], n[15], v[1005];
int main()
{
int i, temp,j, zz = 1;
while(scanf("%d %d %d %d %d %d", &n[0], &n[1], &n[2], &n[3], &n[4], &n[5]))
{
if(n[0] + n[1] + n[2] + n[3] + n[4] + n[5] == 0) break;
printf("Collection #%d:\n", zz++);
V = 0;
for(i = 0; i < N; i++)
{
w[i] = i + 1;
V += w[i]*n[i]; //求总和
}
if(V%2 == 1) //总和是奇数则不能平分
{
printf("Can't be divided.\n\n");
continue;
}
sum = V/2; total = 0;
for(i = 0; i < N; i++) //二进制压缩为——01背包
{
if(n[i] == 0) continue;
temp = 1;
while(n[i] > temp)
{
v[total++] = temp*w[i]; //将新的值赋给v[]
n[i] -= temp;
temp *= 2;
}
v[total++] = n[i]*w[i];
}
memset(bag, 0, sizeof(bag));
for(i = 0; i < total; i++)
{
for(j = sum; j >= v[i]; j--)
{
bag[j] =bag[j]>(bag[j-v[i]]+v[i])?bag[j]:(bag[j-v[i]]+v[i]);
}
}
if(bag[sum] != sum)
printf("Can't be divided.\n\n");
else
printf("Can be divided.\n\n");
}
return 0;
}