HDU 1709 The Balance (生成函数)
题目
http://acm.hdu.edu.cn/showproblem.php?pid=1709
题意
给n个质量为 ai的砝码,可以放在天平的左右两侧,任意组合,问最终有几种质量是称不到的
解法
简单的生成函数的运用
不同的地方在于砝码可以放在另一侧,这样对于砝码i,会有一个\(abs(j-k)\)的情况
代码
#include <cstdio>
#include <cstring>
const int N = 101;
int num[N], ans[N * N];
bool a[N * N], b[N * N];
int main() {
int n;
while(~scanf("%d", &n)) {
int sum = 0;
for(int i = 0; i < n; i++) {
scanf("%d", &num[i]);
sum += num[i];
}
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
/**********生成函数**************************************/
a[0] = a[num[0]] = 1;
for(int i = 1; i < n; i++) { /*第i个表达式*/
for(int j = 0; j <= sum; j++) { /*第i个表达式的第j个变量*/
for(int k = 0; k <= num[i]; k += num[i]) { /*第k个指数*/
b[j + k] += a[j];
b[(j - k) > 0 ? j - k : k - j] += a[j];
}
}
for(int j = 0; j <= sum; j++) {
a[j] = b[j];
b[j] = 0;
}
}
/**********生成函数**************************************/
int cnt = 0;
for(int i = 0; i <= sum; i++) {
if(!a[i]) {
ans[cnt++] = i;
}
}
printf("%d\n", cnt);
if(cnt) {
for(int i = 0; i < cnt; i++) {
if(i == 0) {
printf("%d", ans[i]);
}
else {
printf(" %d", ans[i]);
}
}
printf("\n");
}
}
return 0;
}