对于母函数来说,他的本质解决问题的地方在于“:
1.“把组合问题的加法法则和幂级数的乘幂对应起来。”
2.“把离散数列和幂级数一 一对应起来,把离散数列间的相互结合关系对应成为幂级数间的运算关系,最后由幂级数形式来确定离散数列的构造。 “
例如:分别有一个1克,2克,3克,4克的砝码,问他们能组成几种重量?每种重量能有几种组合方法?解:
用母函数来解决问题,用x来表示砝码,x的指数来表示砝码的重量,现在用函数来表示每个砝码能称的重量:
1个1克的砝码:x^0+x^1
1个2克的砝码:x^0+x^2
依次可以类推:1个3克的砝码:x^0+x^3
1个4克的砝码:x^0+x^4
这几个多项式相乘得到的就是所需要的母函数,每个函数里面的指数表示重量,前面的系数表示的方法数:计算结果为X^0 + X^1 + X^2 + 2*X^3 + 2*X^4 + 2*X^5 + 2*X^6 + 2*X^7 + X^8 + X^9 + X^10。组成10克重量的只有一个方法,4克的有2种方法。
注意:2个2克砝码用的不是x^0+2*x^2,用的是x^0+x^2+x^4.
现有一个问题就是有若干个1克,2克,4克硬币,问能组成的个数:
n个1克硬币:x^0+x^1+x^2+x^3+……
n个2克硬币:x^0+x^2+x^4+x^6+……x^n*2
n个4克硬币:x^0+x^4+x^8+x^12+……+x^n*4
想知道n克硬币的组成重量,就需要计算出x^n前的系数。
就是多项式相乘的原理。
仿照这个代码进行模板。
#include <bits/stdc++.h>
using namespace std;
int main()
{
long long int c1[1500],c2[1500]; //别开小了
int a[]={1,4,9,16,25,36,49,64,81,100,121,144,169,196,225,256,289};
int n;
while(~scanf("%d",&n))
{
if(n==0) break;
for(int i=0;i<=n;i++)
{
c1[i]=1; //最终的值(x的i次方的系数)
c2[i]=0; //临时的情况
}
for(int i=1;i<=16;i++) // 每次的增量 (a数组)
{
for(int j=0;j<=n;j++)
{
for(int k=0;k+j<=n;k+=a[i])
c2[k+j]=c2[k + j]+c1[j];
}
for(int j=0;j<=n;j++)
{
c1[j]=c2[j];
c2[j]=0;
}
}
printf("%lld\n",c1[n]);
}
}