题意:容易理解...
分析:一开始看还不觉得这道题目可以用母函数来做,但是后来想想是关于组合的问题所以就想到了母函数,但是要进行n次母函数,每个团体不加入的时候有多少“获胜联盟”,当加入的时候会多出哪些“获胜联盟”,这就是题目所求,但是我很纳闷的是我开始的思路感觉真的没错,但是答案就是不对,至今还没想通,后来换了种想法才ac了,希望哪位大神能够指出我的错误啊!!
后来的AC代码:
#include<stdio.h> #include<string.h> int n,c1[100001],c2[100001],a[25],sum; int muhanshu(int flag) { int i,j,k,haha=0,ca; int x,y; for(i=0;i<=sum;i++) { c1[i]=0; c2[i]=0; } for(i=1;i<=n;i++) { if(i!=flag) { c1[0]=1; c1[a[i]]=1; ca=i; break; } } for(i=1;i<=n;i++) { if(i==flag||i==ca) continue; for(j=0;j<=sum;j++) { if(c1[j]==0) continue; for(k=0;k<=a[i];k=k+a[i]) c2[j+k]=c2[j+k]+c1[j]; } for(j=0;j<=sum;j++) { c1[j]=c2[j]; c2[j]=0; } } x=sum/2-a[flag]+1; if(x<0) x=0;//这里要注意下,否则会数组越界的 y=sum/2; for(i=x;i<=y;i++) haha=haha+c1[i]; return haha; } int main() { int T,i,max,haha; while(scanf("%d",&T)!=EOF) { while(T--) { sum=0; scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d",&a[i]); sum=sum+a[i]; } if(n==1) { printf("1\n"); continue; } for(i=1;i<=n;i++)//n次母函数 { haha=muhanshu(i); if(i==1) printf("%d",haha); else printf(" %d",haha); } printf("\n"); } } return 0; }
我想不通的代码:
#include<stdio.h> #include<string.h> int n,c1[100001],c2[100001],a[25],sum; int muhanshu(int flag) { int i,j,k,haha=0,ca; for(i=0;i<=sum;i++) { c1[i]=0; c2[i]=0; } for(i=1;i<=n;i++) { if(i!=flag) { c1[0]=1; c1[a[i]]=1; ca=i; break; } } for(i=1;i<=n;i++) { if(i==flag||i==ca) continue; for(j=0;j<=sum;j++) { if(c1[j]==0) continue; for(k=0;k<=a[i];k=k+a[i]) c2[j+k]=c2[j+k]+c1[j]; } for(j=0;j<=sum;j++) { c1[j]=c2[j]; c2[j]=0; } } for(i=sum/2+1;i<=sum;i++) haha=haha+c1[i]; return haha; } int main() { int T,i,max,haha; while(scanf("%d",&T)!=EOF) { while(T--) { sum=0; scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d",&a[i]); sum=sum+a[i]; } max=muhanshu(0); // printf("%d\n",max); for(i=1;i<=n;i++) { haha=muhanshu(i); if(i==1) printf("%d",max-haha); else printf(" %d",max-haha); } printf("\n"); } } return 0; }