母函数就是一列用来展示一串数字的挂衣架。 ——赫伯特·唯尔夫 。

一、普通型母函数


1.定义

对于任意数列 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 G(x) = a_0+a_1x+a_2x^2+...+a_nx^n G(x)=a0​+a1​x+a2​x2+...+an​xn
则称 G ( x ) G(x) G(x)是数列的母函数(generating function)(也叫生成函数)。
其一般形式为:
G ( a n ; x ) = ∑ i = 1 a i x i \displaystyle G(a_n;x)=\sum_{i=1}a_ix^i G(an​;x)=i=1∑​ai​xi

2.应用

组合数学的主要内容是计数,母函数是组合数学中的一个重要理论和工具。那么它是怎么应用的呢?

普 通 型 母 函 数 主 要 是 解 决 求 有 限 多 重 集 的 组 合 普通型母函数主要是解决求有限多重集的组合 普通型母函数主要是解决求有限多重集的组合

设元素 a 1 , a 1 , ⋅ ⋅ ⋅ , a n a_{1},a_{1}, \cdot \cdot \cdot ,a_{n} a1​,a1​,⋅⋅⋅,an​ 互不相同,从有限多重集 { K 1 ⋅ a 1 , K 2 ⋅ a 2 , ⋅ ⋅ ⋅ K n ⋅ a n } \left\{ K_{1} \cdot a_{1},K_{2} \cdot a_{2}, \cdot \cdot \cdot K_{n} \cdot a_{n} \right\} {K1​⋅a1​,K2​⋅a2​,⋅⋅⋅Kn​⋅an​}中选取 r r r 个元素,至少存在一个 K i < r K_{i} < r Ki​<r 时,求其组合。

下面举一个应用实例来理解这个问题:

现在我有两个色子,每个色子有六个面,每个色子掷一次,问两个色子投掷后加起来一共六点的情况有多少种?

我们数一数,根据加法原理:

  • 6 = 1 + 5 = 5 +1
  • 6= 2 + 4 = 4 + 2
  • 6 = 3 + 3

根据乘法原理

  • 第一次取 1,2,3,4,5 共五种方式
  • 由于第一次已经取好,所以第二次的取法是固定的 只有一种

综上,加起来点数为 6 一共是 五 种。

但是如果有 n n n 个色子呢?显然就很难这样计算出来了

我们这时就需要母函数了。
我们可以 x , x 2 , x 3 , x 4 , x 5 , x 6 x,x^2,x^3,x^4,x^5,x^6 x,x2,x3,x4,x5,x6 和 色子的 1 , 2 , 3 , 4 , 5 , 6 1,2,3,4,5,6 1,2,3,4,5,6点映射对应起来。

按照乘法原理,我们可以将两次 色子的投掷看成是 两个 多项式相乘。
例如 投掷 6 点
第一次 投的 是 4 点,第二次是 2 点。和 x 4 x 2 = x 6 x^4 x^2=x^6 x4x2=x6对应起来。

那么第一次投掷可能取 1 , 2 , 3 , 4 , 5 , 6 1,2,3,4,5,6 1,2,3,4,5,6点,这些情况是不可能同时发生的,那么根据加法原理:
第一次投掷就可以和 多项式 ( x + x 2 + x 3 + x 4 + x 5 + x 6 ) (x+x^2+x^3+x^4+x^5+x^6) (x+x2+x3+x4+x5+x6) 形成一个映射关系, x i x^i xi就表示投掷出了 i i i 点。
那么两次投掷的过程就能表示为两个多项式的乘积:
( x + x 2 + x 3 + x 4 + x 5 + x 6 ) ∗ ( x + x 2 + x 3 + x 4 + x 5 + x 6 ) (x+x^2+x^3+x^4+x^5+x^6)*(x+x^2+x^3+x^4+x^5+x^6) (x+x2+x3+x4+x5+x6)∗(x+x2+x3+x4+x5+x6)
乘积的结果是
x 2 + 2 x 3 + 3 x 4 + 4 x 5 + 5 x 6 + 6 x 7 + 5 x 8 + 4 x 9 + 3 x 10 + 2 x 11 + x 12 x^2+2x^3+3x^4+4x^5+5x^6+6x^7+5x^8+4x^9+3x^{10}+2x^{11}+x^{12} x2+2x3+3x4+4x5+5x6+6x7+5x8+4x9+3x10+2x11+x12
x 6 : x 1 x 5 + x 2 + x 4 + x 3 x 3 + x 4 x 2 + x 5 x 1 = 5 x 6 x^6:x^1x^5+x^2+x^4+x^3x^3+x^4x^2+x^5x^1=5x^6 x6:x1x5+x2+x4+x3x3+x4x2+x5x1=5x6

我们发现 x 6 x^6 x6的系数就是两次投掷点数和为 6 的方法数。

到此我们可以得到一个结论:

投掷 m m m 粒色子时,加起来点数的综合化等于 n n n的可能方式的数目为:
G ( x ) = ( x + x 2 + x 3 + x 4 + x 5 + x 6 ) m G(x)=(x+x^2+x^3+x^4+x^5+x^6)^m G(x)=(x+x2+x3+x4+x5+x6)m
展开式中 x n x^n xn的系数。

很明显 G ( x ) G(x) G(x)就是序列 { 1 , 2 , 3 , 4 , 5 , 6 } \{1,2,3,4,5,6\} {1,2,3,4,5,6}的一个母函数,这个例子也很好的说明了母函数的应用:

将计数问题映射成多项式的乘法运算来解决

HDU 1028 Ignatius and the Princess II
题意

给定一个数 N N N,问 N N N拆成若干个整数有多少中拆分方法?

思路
使用母函数进行映射
取 0 个 1 1 1: x 0 x^0 x0
取 1 个 1 1 1: x 1 x^1 x1
取 2 个 1 1 1: x 2 x^2 x2
取 1 1 1 对应的母函数: ( 1 + x + x 2 + . . . + x k + . . . ) (1+x+x^2+...+x^k+...) (1+x+x2+...+xk+...)
取 2 2 2 对应的母函数: ( 1 + x 1 + x 4 + . . . + x 2 k . . . ) (1+x^1+x^4+...+x^{2k}...) (1+x1+x4+...+x2k...)
G ( x ) = ( 1 + x + x 2 + . . . ) ( 1 + x 2 + x 4 + . . . ) ( 1 + x 2 + x 4 + . . . ) ( 1 + x N ) G(x) = (1+x+x^2+...)(1+x^2+x^4+...)(1+x^2+x^4+...)(1+x^N) G(x)=(1+x+x2+...)(1+x2+x4+...)(1+x2+x4+...)(1+xN)

x N x^N xN的系数就是 我们要求的答案。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define ll long long
using namespace std;const int N = 1000;
ll a[N],b[N];
int n;void mother_fun()
{a[0] = 1;for(int i = 1; i <= n ; i++){memset(b,0,sizeof(b));for(int j = 0; j * i <= n; j++){for(int k = 0; k <= n; k++){b[i * j + k] += a[k] ;}}memcpy(a,b,sizeof(b));}
}
int main()
{while(scanf("%d",&n)!= EOF){memset(a,0,sizeof(a));mother_fun();printf("%lld\n",a[n]);}return 0;
}

二、指数型母函数

1.定义

序列 a 1 , a 2 , . . . , a n a_1,a_2,...,a_n a1​,a2​,...,an​的指数型母函数为:
E G ( a n ; x ) = ∑ i = 0 a i x i i ! \displaystyle EG(a_n;x)=\sum_{i = 0}a_i\frac{x^i}{i!} EG(an​;x)=i=0∑​ai​i!xi​

2.应用

从上面的学习,我们可以知道:普通型的母函数是一个解决求有限多重集的组合的有效工具,而指数型函数是
指 数 型 母 函 数 主 要 是 解 决 求 有 限 多 重 集 的 排 列 指数型母函数主要是解决求有限多重集的排列 指数型母函数主要是解决求有限多重集的排列
设元素 a 1 , a 1 , ⋅ ⋅ ⋅ , a n a_{1},a_{1}, \cdot \cdot \cdot ,a_{n} a1​,a1​,⋅⋅⋅,an​互不相同,从有限多重集 { K 1 ⋅ a 1 , K 2 ⋅ a 2 , ⋅ ⋅ ⋅ K n ⋅ a n } \left\{ K_{1} \cdot a_{1},K_{2} \cdot a_{2}, \cdot \cdot \cdot K_{n} \cdot a_{n} \right\} {K1​⋅a1​,K2​⋅a2​,⋅⋅⋅Kn​⋅an​}中选取 r r r 个元素,至少存在一个 K i < r K_{i} < r Ki​<r 时,求其排列。

我们比较普通型母函数和指数型母函数,可以看出普通型的母函数的标志函数为 1 , x , x 2 , . . . , x n 1,x,x^2,...,x^n 1,x,x2,...,xn;而指数型函数的标志函数为 1 , x / 1 ! , x 2 / 2 ! , x 3 / 3 ! . . . , x n / n ! 1,x/1!,x^2/2!,x^3/3!...,x^n/n! 1,x/1!,x2/2!,x3/3!...,xn/n!。
这样的映射也有其意义:

x i i ! \displaystyle\frac{x^i}{i!} i!xi​ 代表的意义是:在某个方案中某个元素出现了 i i i 次,而在不同位置中的 i i i 次出现是相同的。

另外,在指数型母函数使用的过程中,一般都会用到高等数学里的 e x e^x ex的泰勒展开式:
e x = ∑ n = 0 x n n ! = 1 + x + x 2 2 ! + x 3 3 ! . . . + x n n ! + . . . e^x=\sum_{n=0}\frac{x^n}{n!}=1 + x+\frac{x^2}{2!}+\frac{x^3}{3!}...+\frac{x^n}{n!}+... ex=n=0∑​n!xn​=1+x+2!x2​+3!x3​...+n!xn​+...
( e x + e − x ) / 2 = ∑ n = 0 x 2 n 2 n ! = 1 + x 2 2 ! + x 4 4 ! . . . + x 2 n 2 n ! + . . . (e^x+e^{-x})/2=\sum_{n=0}\frac{x^{2n}}{2n!}=1 +\frac{x^2}{2!}+\frac{x^4}{4!}...+\frac{x^{2n}}{2n!}+... (ex+e−x)/2=n=0∑​2n!x2n​=1+2!x2​+4!x4​...+2n!x2n​+...
( e x − e − x ) / 2 = ∑ n = 0 x 2 n + 1 ( 2 n + 1 ) ! = x + x 3 3 ! + x 5 5 ! . . . + x 2 n + 1 ( 2 n + 1 ) ! + . . . (e^x-e^{-x})/2=\sum_{n=0}\frac{x^{2n+1}}{(2n+1)!}= x+\frac{x^3}{3!}+\frac{x^5}{5!}...+\frac{x^{2n+1}}{(2n+1)!}+... (ex−e−x)/2=n=0∑​(2n+1)!x2n+1​=x+3!x3​+5!x5​...+(2n+1)!x2n+1​+...
下面来举个例子:

由 1 , 2 , 3 , 4 1,2,3,4 1,2,3,4四个数字组成的五位数中,要求数 1 1 1出现两次或三次, 2 2 2 最多出现一次, 4 4 4 出现偶数次。

这很明显是一个排列数的问题,在我们有了上述普通型母函数的经验之后,我们可以类似地开始构造我们的指数型母函数:

  1. 1 1 1 出现两次或三次,对应的母函数: x 2 2 ! + x 3 3 ! \displaystyle\frac{x^2}{2!}+\frac{x^3}{3!} 2!x2​+3!x3​

  2. 2 2 2 最多出现 一次,对应的母函数: 1 + x 1 ! \displaystyle1+\frac{x}{1!} 1+1!x​

  3. 3 3 3 出现没有要求, 1 + x 1 ! + x 2 2 ! + x 3 3 ! + . . . + x n n ! + . . . \displaystyle1+ \frac{x}{1!}+ \frac{x^2}{2!} +\frac{x^3}{3!}+...+\frac{x^{n}}{n!}+... 1+1!x​+2!x2​+3!x3​+...+n!xn​+...

  4. 4 4 4 出现偶数次, 1 + x 2 2 ! + x 4 4 ! + x 6 6 ! . . . + x 2 n 2 n ! + . . . \displaystyle1+\frac{x^2}{2!} +\frac{x^4}{4!}+\frac{x^6}{6!}...+\frac{x^{2n}}{2n!}+... 1+2!x2​+4!x4​+6!x6​...+2n!x2n​+...

那么本题的母函数:
G ( x ) = ( x 2 2 ! + x 3 3 ! ) ∗ ( 1 + x 1 ! ) ∗ ( 1 + x 1 ! + x 2 2 ! + x 3 3 ! + . . . + x n n ! + . . . ) ∗ ( 1 + x 2 2 ! + x 4 4 ! + x 6 6 ! . . . + x 2 n 2 n ! + . . . ) \displaystyle G(x) = (\frac{x^2}{2!}+\frac{x^3}{3!})*(1+\frac{x}{1!})*(1+ \frac{x}{1!}+ \frac{x^2}{2!} +\frac{x^3}{3!}+...+\frac{x^{n}}{n!}+...)*(1+\frac{x^2}{2!} +\frac{x^4}{4!}+\frac{x^6}{6!}...+\frac{x^{2n}}{2n!}+...) G(x)=(2!x2​+3!x3​)∗(1+1!x​)∗(1+1!x​+2!x2​+3!x3​+...+n!xn​+...)∗(1+2!x2​+4!x4​+6!x6​...+2n!x2n​+...)

因为, e x = ∑ n = 0 x n n ! = 1 + x + x 2 2 ! + x 3 3 ! . . . + x n n ! + . . . e^x=\sum_{n=0}\frac{x^n}{n!}=1 + x+\frac{x^2}{2!}+\frac{x^3}{3!}...+\frac{x^n}{n!}+... ex=n=0∑​n!xn​=1+x+2!x2​+3!x3​...+n!xn​+...
( e x + e − x ) / 2 = ∑ n = 0 x 2 n 2 n ! = 1 + x 2 2 ! + x 4 4 ! . . . + x 2 n 2 n ! + . . . (e^x+e^{-x})/2=\sum_{n=0}\frac{x^{2n}}{2n!}=1 +\frac{x^2}{2!}+\frac{x^4}{4!}...+\frac{x^{2n}}{2n!}+... (ex+e−x)/2=n=0∑​2n!x2n​=1+2!x2​+4!x4​...+2n!x2n​+...

所以
G ( x ) = ( x 2 2 ! + x 3 3 ! ) ∗ ( 1 + x 1 ! ) ∗ e x ∗ ( e x + e − x ) / 2 G(x)=(\frac{x^2}{2!}+\frac{x^3}{3!})*(1+\frac{x}{1!})*e^x*(e^x+e^{-x})/2 G(x)=(2!x2​+3!x3​)∗(1+1!x​)∗ex∗(ex+e−x)/2
= ( x 2 4 + x 3 3 + x 4 12 ) ∗ ( e 2 x + 1 ) =\displaystyle(\frac{x^2}{4}+\frac{x^3}{3}+\frac{x^4}{12})*(e^{2x}+1) =(4x2​+3x3​+12x4​)∗(e2x+1)
我们要求的是 5 5 5 位数,那么我们的答案就应该是 x 5 5 ! \displaystyle\frac{x^5}{5!} 5!x5​前面的系数。
我们已经有了 x 2 , x 3 , x 4 x^2,x^3,x^4 x2,x3,x4,所以只需要补上 x 3 , x 2 , x 1 x^3,x^2,x^1 x3,x2,x1

将 e 2 x e^{2x} e2x按泰勒展开后,可以得到系数是:

5 ! ∗ ( 1 4 ∗ 2 3 3 ! + 1 2 ∗ 2 2 2 ! + 1 12 ∗ 2 1 1 ! ) = 140 5!*(\frac{1}{4}*\frac{2^3}{3!}+\frac{1}{2}*\frac{2^2}{2!}+\frac{1}{12}*\frac{2^1}{1!})=140 5!∗(41​∗3!23​+21​∗2!22​+121​∗1!21​)=140

HDU 1521 排列组合
题意

有n种物品,并且知道每种物品的数量。要求从中选出m件物品的排列数。例如有两种物品A,B,并且数量都是1,从中选2件物品,则排列有"AB","BA"两种。

思路

根据题意,这是一个多重集的排列数问题,所以考虑使用指数型生成函数,然后就是一顿模板。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define ll long long
using namespace std;const int N = 107;
int n,m;
int num[N];
double a[N] = {0},b[N] = {0};
//求阶乘
int fac(int n) {int res = 1;for(int i = 1; i <= n; i++) res *= i;return res;
}
//指数型母函数
void mother_fun() {for(int i = 0; i <= num[1]; i++) a[i] = 1.0 / fac(i);for(int cur = 2; cur <= n; cur++) {memset(b,0,sizeof(b));for(int i = 0 ; i <= num[cur]; i++) {for(int k = 0; k  + i <= m; k++) {b[i + k] += a[k] / fac(i) ;}}memcpy(a,b,sizeof(b));}printf("%.0lf\n",a[m]*fac(m));
}
int main() {//freopen("data.in","r",stdin);while(scanf("%d%d",&n,&m)!= EOF) {memset(a,0,sizeof(a));for(int i = 1; i <= n; i++) scanf("%d",num + i);mother_fun();}return 0;
}

快乐地打牢基础(13)——普通型母函数和指数型母函数的应用相关推荐

  1. 快乐地打牢基础(4)——树状数组

    在解题的过程中,我们想维护一个数组的前缀和s[i] = A[1] + A[2] +-+A[i].我们改变任意一个A[i],那么S[i]之后都会发生变化,朴素写法调整前缀和S最坏的情况需要O(n)的时间 ...

  2. 快乐地打牢基础(1)——二分与三分

    二分是一种常用且非常精妙的算法,常常是我们解答问题的突破口.二分的基本用途是在单调序列或单调函数中做查找操作.因此当问题的答案具有单调性时,就可以通过二分把求解转换为判定(根据复杂度理论,可知判定的难 ...

  3. 快乐地打牢基础(5)——割点和桥

    一.定义 割点集合: 在一个无向连通图中,如果有一个顶点集合V,删除顶点集合V以及与V中顶点相连(至少有一端在V中)的所有边之后,原图不连通,就称这个点为割点集合. 一个图的点连通度: 最小割点集合的 ...

  4. 【组合数学】指数型母函数 应用 ( 多重集排列问题 | 不同球放在不同盒子里 | 奇/偶数序列的指数生成函数推导 )

    文章目录 多重集全排列公式 指数型母函数 处理多重集排列问题 引入 指数型母函数 处理多重集排列问题 公式推导 指数型母函数 处理 有限数字串问题 指数型母函数 处理 n 位数字串问题 指数型母函数 ...

  5. [.net 面向对象编程基础] (13) 面向对象三大特性——多态

    [.net 面向对象编程基础] (13) 面向对象三大特性--多态 前面两节,我们了解了面向对象的的封装和继承特性,面向对象还有一大特性就是多态.比起前面的封装和继承,多态这个概念不是那么好理解.我们 ...

  6. 命名空间_python基础 13 类命名空间于对象、实例的命名空间,组合方法

    python基础 13 类命名空间于对象.实例的命名空间,组合方法 1.类命名空间于对象.实例的命名空间 创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性 而类有两 ...

  7. Java基础13:反射与注解详解

    Java基础13:反射与注解详解 什么是反射? 反射(Reflection)是Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性. Orac ...

  8. 作业1 OO基础1-3、 设计一个教师类Teacher(属于cn.net.sdkd包)

    作业1 OO基础1-3. 设计一个教师类Teacher(属于cn.net.sdkd包) 要求: 1)属性有编号(int no).姓名(String name).年龄(int age).所属学院(Str ...

  9. 【Grasshopper基础13】创建可在画布上自由传递的自定义类型数据(上)—— IGH_Goo接口的重要性及其实现

    接下来的两章,我们来介绍一下在之前章节尚未介绍到的,但却在Grasshopper中占据极其重要地位的另一批我们早就虎视眈眈但却还没想到理由要去触碰的电池们(左侧红色框指示): 是的,就是这一些带黑底的 ...

最新文章

  1. 020_html格式化
  2. 为什么有时候 php 没有写闭合标签结束符?
  3. 机器人 铑元素_中国青年化学家元素周期表专辑 | 胡淑贤:我为镨代言
  4. Smarty目录结构和子目录路径问题
  5. Docker学习文档之三 其他相关-安全性
  6. 20135304刘世鹏——信息安全系统设计基础第九周总结
  7. OPENSSH升级为7.4
  8. ue4如何恢复初始状态_UnrealEngine4初始化流程
  9. Android 存储学习之在内部存储中读写文件
  10. java数字金额大写金额_Java实现 将数字金额转为大写中文金额
  11. python正则取反,一文搞定Python正则表达式
  12. Science | 再野化植物微生物组——作物祖先微生物群可能为提高可持续的粮食生产提供了一种方法...
  13. 改进YOLOv5系列:最新ConvNeXt结合YOLO | CVPR2022 多种搭配,即插即用 | Backbone主干CNN模型
  14. 命名空间提示“http://schemas.microsoft.com/xaml/behaviors”不存在Interation的解决办法
  15. Pandas 中 Series 和 DataFrame 知识点
  16. 阿里云倒逼亚马逊提高市场竞争?AWS CEO安迪·贾西谈量子计算与AI
  17. 【云宏大讲坛】关键应用在超融合环境下的实践
  18. 25个常用的防火墙规则
  19. HTAP 快速上手指南
  20. java实行excel cell内换行

热门文章

  1. qt for python教程_PyQt教程 - pythonQt的安装和配置及版本间差异
  2. Oracle笔记 之 分组统计排名函数dense_rank/rank()-over()函数
  3. 阿里云开放redis 端口 6379
  4. 基于android的理财软件技术,基于Android的个人理财系统的设计与实现
  5. MX450和MX330的区别
  6. 水处理行业必看:盐湖卤水中分离硼的工艺盘点
  7. Spring线程池异步传递MDC信息
  8. 手把手教你写android项目@第一期项目——身份证查询创新
  9. vuecli3.0热更新失效问题解决
  10. webpack项目配置与启动流程