多重背包问题,可以把每个东西看成重量为 i 价值为 i 的 n[i] 个物品。
然后看是否能否装满一个容量为总价值一半的背包即可!
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX = 6;
const int MAXN = 20000 * 6 + 5;
int n[MAX], dp[MAXN], ca = 1, v;
void zop(int p, int w){
for(int i = v; i >= p; --i)
dp[i] = max(dp[i], dp[i - p] + w);
}
void cp(int p, int w){
for(int i = p; i <= v; ++i)
dp[i] = max(dp[i], dp[i - p] + w);
}
void mp(int p, int w, int a){
if(p * a >= v){
cp(p, w);
return;
}
for(int i = 1; i < a; a -= i, i <<= 1)
zop(p * i, w * i);
zop(p * a, w * a);
}
int main(){
while(1){
int sum = 0;
for(int i = 0; i < MAX; ++i)
scanf("%d", n + i), sum += n[i] * (i + 1);
if(sum == 0)
break;
printf("Collection #%d:\n", ca++);
if(sum % 2 == 1){
printf("Can't be divided.\n\n");
continue;
}
v = sum / 2;
memset(dp, 0, sizeof(dp));
for(int i = 0; i < MAX; ++i){
mp(i + 1, i + 1, n[i]);
}
if(dp[v] == v)
printf("Can be divided.\n\n");
else
printf("Can't be divided.\n\n");
}
return 0;
}