HDU 1709 The Balance

HDU_1709

    这个题目还是满好玩的,砝码还可以放到异侧,因此如果用生成函数的话每项可以构造成(x^(-ai)+1+x^ai),然后展开的时候把x的负数次方的系数也算一下,但实际上还有更简单的处理方式,只要在计算x^(-ai)的系数的时候一并累加到x^ai上即可。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAXD 110
#define MAXM 20010
int wa[MAXM], wb[MAXM], weight[MAXD], N, S, *a, *b, ans[MAXM];
void init()
{
int i, j, k;
S = 0;
for(i = 1; i <= N; i ++)
{
scanf("%d", &weight[i]);
S += weight[i];
}
}
void solve()
{
int i, j, k, *t, cnt;
a = wa, b = wb;
memset(b, 0, sizeof(b[0]) * (S + 1));
b[0] = 1;
for(i = 1; i <= N; i ++)
{
memset(a, 0, sizeof(a[0]) * (S + 1));
for(j = 0; j < 2; j ++)
for(k = 0; k + weight[i] * j <= S; k ++)
{
a[k + weight[i] * j] |= b[k];
a[abs(k - weight[i] * j)] |= b[k];
}
t = a, a = b, b = t;
}
cnt = 0;
for(i = 1; i <= S; i ++)
if(!b[i])
ans[cnt ++] = i;
printf("%d\n", cnt);
if(cnt)
{
printf("%d", ans[0]);
for(i = 1; i < cnt; i ++)
printf(" %d", ans[i]);
printf("\n");
}
}
int main()
{
while(scanf("%d", &N) == 1)
{
init();
solve();
}
return 0;
}


你可能感兴趣的:(HDU)