玻璃求的价值有1,2,3,4,5,6分别有c[1],c[2],c[3],c[4],c[5],c[6].个。最后判断dp[sum/2] 是否和sum/2相等。sum为所有玻璃球的价值总和,显然的多重背包问题.
/*********************
* Author:fisty
* Data:2014-11-22
* hdu1059
* 多重背包
* *******************/
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAX_V 10
#define MAX_N 200000
int main(){
int c[MAX_V];
int kcase = 1;
while(scanf("%d%d%d%d%d%d", &c[1], &c[2], &c[3], &c[4], &c[5], &c[6]) != EOF){
int cnt = 0; //有价值的数目
int sum = 0;
int n = 6;
int dp[MAX_N];
memset(dp, 0, sizeof(dp));
for(int i = 1;i <= n; i++){
if(c[i] != 0){
sum += c[i]*i;
cnt++;
}
if(cnt == 0 && i == 6)
return 0;
}
printf("Collection #%d:\n", kcase++);
if(sum % 2){
printf("Can't be divided.\n\n");
}else{
sum = sum / 2;
for(int i = 1;i <= n; i++){
if(c[i] * i >= sum){
for(int j = i; j <= sum; j++){
dp[j] = max(dp[j], dp[j-i] + i);
}
}else{
int v = 1;
while(v <= c[i]){
for(int j = sum; j >= v*i; j--){
dp[j] = max(dp[j], dp[j-v*i] + v*i);
}
c[i] -= v;
v *= 2;
}
for(int j = sum ; j >= i*c[i]; j--){
dp[j] = max(dp[j], dp[j-i*c[i]] + i*c[i]);
}
}
}
if(dp[sum] == sum){
printf("Can be divided.\n\n");
}else{
printf("Can't be divided.\n\n");
}
}
}
return 0;
}