题目链接
母函数的多项式构造相关知识
下面是这题的母函数做法以及自己写的一些注释。应该很详尽了。
#include<stdio.h>
#include<string.h>
int arr[27]; //存储26个字母的每个字母的个数
int c1[52]; //最后存储每个value出现的方案数目
int c2[52]; //c1的中间数组
int main(){
int n;
while(scanf("%d",&n)!=EOF){ //扫描有几行数据
while(n--){ //按行读取数据
for(int i=1;i<=26;i++){
scanf("%d",&arr[i]);//读取26字母的对应最多出现个数
}
memset(c1,0,sizeof(c1)); //初始化c1,注意放在n--的内部,这样不会让上一次的结果影响下一次
memset(c2,0,sizeof(c2)); //初始化c2
for(int i=0;i<=arr[1];i++){/*把第一个括号中项的次数置为一
(i<arr[1]中i表示次数,arr[i]是第一个括号内的最高次数,
将c1初始化为第一个括号内的内容)*/
c1[i]=1;
}
for(int i=2;i<=26;i++){ //i代表是第几个括号内的内容
for( int j =0;j<=50;j++){ //j代表当前结果的次数,c1[j]是迭代到这个括号之前,j次幂的系数,因为要<=50所有最多到50次幂
for(int k =0;k<=arr[i]*i&&k+j<=50;k+=i)//k代表的是现在这个括号的次数,k<=arr[i]*i代表这个括号的最高次幂是arr[i]*i
c2[k+j]+=c1[j]; //代表k与j次幂相乘,变成k+j次幂,但是系数还是j次的系数,因为k次的系数为1
}
for(int j=0;j<=50;j++){ //把c2的中间结果存储到结果数组c1中
c1[j]=c2[j];
c2[j]=0; //c2数组全部置为0;以便进行下一次迭代
}
}
int max=0;
for(int i=1;i<=50;i++){ //题目需要小于等于50的方案数目,所以把1-50全部累加和得到结果
max+=c1[i];
}
printf("%d\n",max);
}
}
return 0;
}