千辛万苦找到原题:Dividing
觉得这题有一个多重背包优化灰常ok。
可以发现所有数都可被2的n次方组合!!!那么,我们就不用枚举k个弹子辽。
#include<cstdio>
#include<iostream>
using namespace std;
int a[20002], sum, T, len, dp[720002], w[720002];
bool f;
int main() {
while(1) {
f = 0;
sum = 0;
len = 0;
for(int i = 1; i <= 6; i ++) {
scanf("%d", &a[i]);
sum += a[i] * i;
if(a[i])
f = 1;
}
if(! f)
return 0;
printf("Collection #%d:\n", ++ T);
if(sum & 1) {
printf("Can't be divided.\n");
continue;
}
for(int i = 1; i <= 6; i ++)
for(int j = 1; j <= a[i]; j <<= 1)
w[++ len] = i * j;
sum >>= 1;
dp[0] = 1;
for(int i = 1; i <= len; i ++)
for(int j = sum; j >= w[i]; j --)
dp[j] = max(dp[j], dp[j - w[i]]);
if(dp[sum])
printf("Can be divided.\n");
else
printf("Can't be divided.\n");
}
return 0;
}
不过我们发现,w[]中有些值是重复的。可以用bool判重或sort再判重(感觉也没啥用哇哈哈)。
如果有问题,请大佬们在评论区落座吧。