生成函数(母函数)--详解+例题

生成函数

百度百科:在数学中,某个序列的母函数(Generating
function,又称生成函数)是一种形式幂级数,其每一项的系数可以提供关于这个序列的信息。使用母函数解决问题的方法称为母函数方法。

总结一下来说就是一句话:
既然是总结那就最后再回来看

把组合问题的加法法则和幂级数的的乘幂的相加对应起来

母函数分为很多种,包括普通母函数、指数母函数、L级数、贝尔级数和狄利克雷级数等。这里就细讲一下普通型母函数。

普通型母函数:
定义:对于任意数列 a 0 , a 1 , a 2 . . . a n a_0, a_1, a_2...a_n a0,a1,a2...an即用如下方法与一个函数联系起来:

G(x) = a 0 + a 1 x + a 2 x 2 + . . . + a n x n a_0+a_1x+a_2x^2+...+a_nx^n a0+a1x+a2x2+...+anxn

则称G(x)是数列a的生成函数。

引用 oi-wiki
常见的普通生成函数有:
1.序列a = {1, 2, 3}的普通生成函数是1+2x+3x^2。
2.序列a = {1,1,1,…}的普通生成函数是 ∑ 0 n x i \sum_0^nx^i 0nxi
3.序列a = {1,2,4,8,16…}的生成函数是 ∑ 0 n 2 n x i \sum_0^n2^nx^i 0n2nxi
即:g(x) = 1 + 2 x + 4 x 2 + 8 x 4 + . . . 1+2x+4x^2+8x^4+... 1+2x+4x2+8x4+...
4.序列a = {1,3,5,7,9,…}的生成函数是 ∑ 0 n ( 2 n + 1 ) x n \sum_0^n(2n+1)x^n 0n(2n+1)xn

换句话说,如果序列 a 有通项公式,那么它的普通生成函数的系数就是通项公式。

封闭形式

在运用生成函数的过程中,我们不会一直使用形式幂级数的形式,而会适时地转化为封闭形式以更好地化简。

例如 {1,1,1,…}的普通生成函数 F ( x ) = ∑ 0 n x i F(x)=\sum_0^nx^i F(x)=0nxi,我们发现
F ( x ) x + 1 = F ( x ) F(x)x + 1=F(x) F(x)x+1=F(x) ------> F ( x ) = 1 1 − x F(x)=\frac{1}{1-x} F(x)=1x1
这就是 F ( x ) = ∑ 0 n x i F(x)=\sum_0^nx^i F(x)=0nxi的封闭形式

常用生成函数的封闭形式推导
1.a = {0,1,1,1,…}。
2.a = {1,0,1,0,1,…}。
3.a = {1,2,3,4,…}。
4. a n = C n m a_n=C_n^m an=Cnm(m是常数, n ≥ 0 n\geq0 n0)。
5. a n = C m + n n a_n=C_{m+n}^n an=Cm+nn(m是常熟, n ≥ 0 n\geq0 n0)。

1. F ( x ) = ∑ 1 n x i = x 1 − x F(x)=\sum_1^nx^i=\frac{x}{1-x} F(x)=1nxi=1xx
2. F ( x ) = ∑ 0 n x 2 i = 1 1 − x 2 F(x)=\sum_0^nx^{2i}=\frac{1}{1-x^2} F(x)=0nx2i=1x21
3. F ( x ) = ∑ 1 n ( i + 1 ) x i = 1 1 − x 2 F(x)=\sum_1^n(i+1)x^i=\frac{1}{1-x^2} F(x)=1n(i+1)xi=1x21
4.二项式定理: F ( x ) = ∑ 0 i C i m x i = ( 1 + x ) m F(x)=\sum_0^iC_i^mx^i=(1+x)^m F(x)=0iCimxi=(1+x)m
5. F ( x ) = ∑ 0 i C i + m i x i = 1 ( 1 − x ) m + 1 F(x)=\sum_0^iC_{i+m}^ix^i=\frac{1}{(1-x)^{m+1}} F(x)=0iCi+mixi=(1x)m+11

说了这么多算是对生成函数有了一个初步的了解的吧

上例题

例一:
有1克,2克,3克,4克的砝码各一枚,能称出哪几种重量?每种重量各有几种可能方案?

分析:对于每一种砝码我们都有取和不取的操作,我们拿前两种砝码来看一共有:(选1g||不选1g)&&(选2g||不选2g) 中方案。

用母函数来解决这个问题就是:
每种砝码有两种状态

1g砝码用函数 1 + x 1 1+x^1 1+x1表示
2g砝码用函数 1 + x 2 1+x^2 1+x2表示
3g砝码用函数 1 + x 3 1+x^3 1+x3表示
4g砝码用函数 1 + x 4 1+x^4 1+x4表示

其中x表示砝码,x的指数表示砝码的重量
取4g砝码来说 1 + x 4 1+x^4 1+x4应写成 1 x 0 + x 4 1x^0+x^4 1x0+x4 其中 1 x 0 1x^0 1x0表示重量为4g的砝码数量为0个, 1 x 4 1x^4 1x4表示重量为4g的砝码数量为1个

我们将这四种砝码能取得状态相乘,也就是卷积。
( 1 + x ) ( 1 + x 2 ) ( 1 + x 3 ) ( 1 + x 4 ) (1+x)(1+x^2)(1+x^3)(1+x^4) (1+x)(1+x2)(1+x3)(1+x4)
结果为:(1 + x + x2 + 2x3 + 2x4 + 2x5 + 2x6 + 2x7 + x8 + x9 + x10)
得出可以称出1g到10g,系数就是方案数。这里也就是最开始说的那句话的体现之处。

例二:

求用1分、2分、3分的邮票贴出不同数值的方案数:
例一和例二有什么区别?例一每种是一个,而例二每种是无限的。

生成函数: g ( x ) = ( 1 + x + x 2 + x 3 + . . . ) ( 1 + x 2 + x 4 + x 6 + . . . ) ( 1 + x 3 + x 6 + x 9 + . . . ) g(x)=(1+x+x^2 +x^3+...)(1+x^2 +x^4 +x^6 +...)(1+x^3+x^6 +x^9+...) g(x)=(1+x+x2+x3+...)(1+x2+x4+x6+...)(1+x3+x6+x9+...)

将其展开其中每一项的指数就是n,其系数就是对应方案数。
这题跟整数拆分是同样道理
整数拆分:HDU1028
题意:将整数n拆成若干整数的和,问有多少种方案数?

代码加超详细注释

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5 + 10;

int a[maxn], b[maxn];
//a[] 保存各项质量砝码可以组合的数目
//b[] 是中间量, 保存每一次的情况 
/*
	g(x) = (1+x+x^2+x^3+x^4+...)*(1+x^2+x^4+x^6+x^8+...)*(1+x^3+x^6+x^9+...)...
	每一种都有无限个 第i个括号表示第i个数可以取的所有状态
*/
int main(){
	int n;
	while(cin >> n){
		for(int i=0; i<=n; i++){
			a[i] = 1; // 对1 + x + x^2 + x^3 + ... 初始化系数为1   1-n个数都有一种方案(全由1组成) 
			b[i] = 0; //作为滚动数组 初始化为0 用来累加每个括号的乘法运算 
		}
		for(int i=2; i<=n; i++){ // 和第i个括号进行乘积 
			for(int j=0; j<=n; j++){ // 表示前i个括号乘积表达式中每一项的系数 
				for(int k=0; k+j<=n; k+=i){ // 表示第j个指数 每次自增i(因为第i个表达式的增量是i)
					//将相同指数项 的系数相加 
					//j+k则表示乘法中指数相加 
					b[j+k] += a[j]; // a[j]是新进入乘法的那个括号中系数
				}
			}
			for(int j=0; j<=n; j++){ //滚动数组 
				a[j] = b[j];
				b[j] = 0;
			}
		}
		cout << a[n] << endl;
	}
	return 0;
}

…剩余生成函数有时间再补充
创作不易若有奇怪的知识增加留个赞吧
引用某些博主的文章,如有问题请私。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值