稍微变了一点的母函数,因为砝码可以摆在左右两边,所以我们可以令母函数为(x^-i+1+x^i),当x的指数为负时,表示砝码与重物放在一边,其他砝码则在另一边
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
int n;
int sum;
int a1[12000],a2[12000];
int a[105];
int ans[10005];
void solve(){
memset(a1,0,sizeof(a1));
memset(a2,0,sizeof(a2));
memset(ans,0,sizeof(ans));
a1[0]=a1[a[1]]=1;
for(int i=2;i<=n;i++){
for(int j=0;j<=sum;j++){
for(int k=0;k+j<=sum&&k<=a[i];k+=a[i]){
if(j>k)
a2[j-k]+=a1[j];
else
a2[k-j]+=a1[j];
a2[k+j]+=a1[j];
}
}
for(int j=0;j<=sum;j++){
a1[j]=a2[j];
a2[j]=0;
}
}
int cnt=0;
for(int i=1;i<=sum;i++){
if(a1[i]==0){
ans[cnt++]=i;
}
}
if(cnt==0){
printf("%d\n",0);
}
else{
printf("%d\n",cnt);
for(int i=0;i<cnt;i++){
if(i==0)
printf("%d",ans[i]);
else{
printf(" %d",ans[i]);
}
}
printf("\n");
}
return;
}
int main(){
while(scanf("%d",&n)!=EOF){
sum=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
sum+=a[i];
}
solve();
}
return 0;
}