一.引出母函数
母函数,也就是生成函数,在ACM中常常用于求解组合数学的计数问题。
一般的,能用母函数做的题,也能用其它方法(诸如推规律啦,DP啦)等等来做,母函数的复杂度为O(n^3),可以说是非常高了,所以只有在数据特别小且实在想不到其他方法求解的时候才可以尝试一下用母函数来做
那么,什么是母函数呢?
二.母函数的内容与例子
把一个已知的序列和x的多项式{x^0, x^1, x^2, … , x^n}合并起来,产生的新的多项式就叫做原来序列的母函数。
例如:序列{1, 0, 2, 4, 3, 1, 2}的母函数为f(x) = 1✖️x^0 + 0✖️x^1+ 2✖️x^2 + 4✖️x^3 + 3✖️x^4 + 1✖️x^5 + 2✖️x^6;
下面就讲解两道例题,来说明母函数的用法:
1.例如有1g, 2g, 3g, 4g砝码各一枚,问能称几种重量,每种重量的方案数?
1g砝码就是x^0 + x^1,2g砝码就是 x^0 + x2,3g砝码就是x0 + x3,4g砝码就是x0 + x^4
把他们累乘并化简,得到:1 + x + x^2 + 2✖️x^3 + 2✖️x^4 + 2✖️x^5 + 2✖️x^6 + 2✖️x^7 + x^8 + x^9 + x^10
我们从方程式可知,可以称0~10种重量,其中3~7有两种称法,其余一种
2.有1分,2分,3分邮票无限,问贴出不同数值的方案数 (数值小于等于100)?
一分邮票可表示为(x^0 + x^1 + x^2 + x^3 + …+ x^100)
二分邮票可表示为(x^0 + x^2 + x^4 + x^6 + …+ x^100)
三分邮票可表示为(x^0 + x^3 + x^6 + x^9 + …+ x^99)
将三者累乘即可得到如例1中的方程式,即可一眼得到答案(可利用剪枝省略数值>100的部分)
三.母函数的代码实现
我们拿第2个例子来说:
ll N = 100; //设置上界
ll c1[N + 5]; //c1[i]为最终多项式幂为i的系数
ll c2[N + 5]; //c2为临时合并的多项式
void init() {
c1[0] = 1; //初始化0的情况算1种
for (int i = 1; i <= 3; i++) { //遍历每种邮票
for (int j = 0; j <= N; j += i) { //该种邮票存在的次幂j
for (int k = 0; j + k <= N; k++) {
c2[j + k] += c1[k] * 1; //因为每种邮票的不同次幂系数都为1
}
}
for (int j = 0; j <= N; j++) { //将中间状态c2转移到c1并清空c2
c1[j] = c2[j];
c2[j] = 0;
}
}
}
//c1[i]即为组成i分钱的方案数
如果有写的不对或者不全面的地方 可通过主页的联系方式进行指正,谢谢