先来看一个多项式:
可以看出,x^2的系数是由a1,a2,a3,......an,两两组合的结果,x^3的系数是由它们三三的组合的结果,依次类推。
若令a1=a2= …=an=1,在(8-1)式中a1a2+a1a3+...+an-1an项系数中每一个组合有1个贡献,其他各项以此类推。故有:
对于序列a0,a1,a2,…构造一函数:
此函数就称为序列a1,a2,a3,.....的母函数。
其中x幂的系数对应组合成x次幂的方案数。
下面以hdu2082给出母函数的模板,
#include<stdio.h>
#include<string.h>
int main()
{
<span style="white-space:pre"> </span>int c1[60],c2[60];
<span style="white-space:pre"> </span>int b[30];
<span style="white-space:pre"> </span>int t,i,j,k,sum;
<span style="white-space:pre"> </span>scanf("%d",&t);
<span style="white-space:pre"> </span>while(t--)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>for(i=1;i<=26;i++)
<span style="white-space:pre"> </span> scanf("%d",&b[i]);
<span style="white-space:pre"> </span>memset(c1,0,sizeof(c1));
<span style="white-space:pre"> </span>memset(c2,0,sizeof(c2));
<span style="white-space:pre"> </span>for(i=1;i<=26;i++)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>if(b[i]!=0)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>for(j=0;j*i<=b[i]*i&&j<=b[i];j++)
<span style="white-space:pre"> </span> c1[j*i]=1;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>break;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>c1[0]=1;
<span style="white-space:pre"> </span>for(i=i+1;i<=26;i++) //----------------1
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>for(j=0;j<=50;j++) //------------------2
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>for(k=0;k+j<=50&&k<=b[i]*i;k+=i)//-3
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>c2[k+j]+=c1[j];
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>for(j=0;j<=50;j++) //-----------4
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>c1[j]=c2[j];c2[j]=0;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>sum=0;
<span style="white-space:pre"> </span>for(i=1;i<=50;i++)
<span style="white-space:pre"> </span> sum+=c1[i];
<span style="white-space:pre"> </span>printf("%d\n",sum);
<span style="white-space:pre"> </span>}
return 0;
}
其中:
<pre name="code" class="objc">for(i=1;i<=26;i++)
<span> </span>{
<span> </span>if(b[i]!=0)
<span> </span>{
<span> </span>for(j=0;j*i<=b[i]*i&&j<=b[i];j++)
<span> </span> c1[j*i]=1;
<span> </span>}
<span> </span>break;
<span> </span>}
这里相当于对母函数中第一个括号,对其对应的x次幂初始化;
下面的三重循环中,
循环1:i从i+1(第一个字母个数不为零的下一个)开始,遍历到第二十六个,这里的i就是第i个表达式。
循环2;j从零到50,这里j就相当于前面i表达式相乘的结果中第j个变量;
循环3:k,<p style="color: rgb(51, 51, 51); font-family: Arial; font-size: 14px; line-height: 26px;">k表示的是第j个指数,所以k每次增i(因为第i个表达式的增量是i)。
循环4 、把c2的值赋给c1,而把c2初始化为0,因为c2每次是从一个表达式中开始的
</p>