题目:http://acm.hdu.edu.cn/showproblem.php?pid=2082
题意:已知有26种数字(1,2,3,4......26),然后输入26个数(m1,m2,m3,....m26),分别代表每个数字的个数,求出总值不超过50的方案数。
分析:由于每种数字各选多少个互不影响。
对于数字1,有m1个,用多项式(1+x+x^2+x^3+....+x^m1)表示选数字1的总方案,1(x^0)表示不选,x(x^1)表示选一个1,x^2表示选两个1,.......,x^m1表示选m1个1。
对于数字2,有m2个,用多项式(1+x^2+x^4+x^6+.....+x^(2*m2))表示选数字2的总方案,1表示不选,x^2表示选一个2,x^4表示选两个2,.......,x^(2*m2)表示选m2个2。
。。。。。。
构造母函数如下:
G(x)=(1+x+x^2+x^3+....+x^m1)*(1+x^2+x^4+x^6+.....+x^(2*m2))......(1+x^26+x^52+....+x^(26*m26))
展开后如下:
G(x)=1+(p1)x+(p2)x^2+(p3)x^3+........
x指数幂代表总值,x的系数代表其方案数。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
int a[60],t[60];
int ncase,x;
int i,j,k;
scanf("%d",&ncase);
while(ncase--)
{
memset(a,0,sizeof(a));
memset(t,0,sizeof(t));
for(i=1;i<=26;i++)
{
scanf("%d",&x);
a[0]=1;
for(j=0;j<=50;j++)
for(k=0;k<=x && i*k+j<=50 ;k++)
t[i*k+j]+=a[j];
for(j=0;j<=50;j++)
a[j]=t[j];
memset(t,0,sizeof(t));
}
int ans=0;
for(i=1;i<=50;i++)
ans+=a[i];
printf("%d\n",ans);
}
return 0;
}