前辈的优秀博客
母函数入门+模板http://blog.csdn.net/vsooda/article/details/7975485#reply
http://blog.csdn.net/winter2121/article/details/55535894
例一:解决砝码问题:若有1克、2克、3克、4克的砝码各一 枚,能称出哪几种重量?各有几种可能方案?
考虑构造母函数,如果用x的指数表示称出来的重量,则
1个1克的砝码可以用函数1+x表示,
1个2克的砝码可以用函数1+x2表示,
1个3克的砝码可以用函数1+x3表示,
1个4克的砝码可以用函数1+x4表示,
(1+x)(1+x^2)(1+x^3)(1+x^4)
=(1+x+x^2+x^3)(1+x^3+x^4+x^7)
=1+x+x^2+2x^3+2x^4+2x^5+2x^6+2x^7+x^8+x^9+x^10
从上面的函数知道,可称出从1 g到10g,系数就是方案数
例如右端有2x5项,即称出5克的方案有2:5=3+2=4+1;同样,6=1+2+3=4+2;10=1+2+3+4。
故称出6克的方案有2,称出10克的方案有1
问题二:求用1分,2分,3分的邮票贴出不同数值的方案数(邮票是无限数量的)
母函数为:G(x)=(1+x+x^2+x^3+....)*(1+x^2+x^4+....)*(1+x^3+x^6+....)
母函数:(1+x+x^2+x^3)*(1+x^2+x^4+x^6+x^8)*(1+x^4+x^8)
问题四:整数n拆分成1,2,3,…,m的和,求其母函数。
母函数:(1+x^1+x^2+...)(1+x^2+x^4+...)(1+x^3+x^6+...)....(1+x^m+x^2m+....)
然后求出x^n的系数即为方案数
母函数:(1+x^1+x^2+...)(1+x^2+x^4+...)(1+x^3+x^6+...)....(1+x^m+x^4m+....)
然后求出x^(n-m)的系数即为方案数
母函数:(x^4+x^5+...+x^10)*(1+x^1+x^2+x^3+x^4+x^5)(1+x^2+x^4+x^6+x^8+x^10)(1+x+x^2+..x^10)
怎么样实现这个母函数运算呢;
用计算机模拟人算的结果
举个例子:
(1+x)*(1+x^2)*(1+x^3)
1 先算前两个括号
拿1先 乘后面一个括号得到1+x^2,然后再拿x乘后面一个括号得到x+x^3
然后相加得到 1+x+x^2+x^3
2然后再算剩下两个括号
(1+x+x^2+x^3)*(1+x^3)
步骤同上
现在以 每种种类无限为例给出模板。自己用的时候要变通
#include<iostream>
using namespace std;
const int _max=10001;
int c1[_max];//c1 是保存各项质量砝码可以组合的数目
int c2[_max];//c2 是中间量 ,保存每一次的情况
int main()
{
int nNum;
int i,j,k;
while(cin>>nNum)
{
for(i =0;i<=nNum;++i)//对c1 初始化,由第一个表达式( 1+x+x^2+..+x^n)初始化
{
c1[i]=1;
c2[i]=0;
}
for(i=2;i<=nNum;i++)//第一个式子 依次跟后面相乘
{
for(j=0;j<=nNum;++j)//j从0到n遍历,这里的j就是(前面i个表达式累乘的表达式) 里的第j个变量
for(k=0;k+j<=nNum;k+=i)//k 表示第j个指数,所以k每次增i 因为第i个表达式 的增量为i
{
c2[j+k]+=c1[j];
}
for(j=0;j<=nNum;j++)//把c2的值赋给c1,而把c2初始化为0 ,因为c2每次是从一个表达式开始的
{
c1[j]=c2[j];
c2[j]=0;
}
}
}
return 0;
}