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;
}

Source

HDU 2007-Spring Programming Contest

posted @ 2015-08-06 08:49  ACM_Record  阅读(465)  评论(0编辑  收藏  举报