小学生都能看懂的生成函数入门教程

本博客正在牛客参与评比活动,喜欢的话来点个赞吧~

前言

第一次当标题党真是有点不适应php

如今网上讲生成函数的教程大多都是从\(\frac{1}{1-x} = \sum_{i=0}^{\infty}x^i, e^x = \sum_{i=0}^{\infty} \frac{x^i}{i!}\)开始,可是我不认为这样有助于你们理解生成函数的本质。我最开始学的时候也是在这里蒙了很久,直到看到了朱全民老师的课件,才真正的理解了生成函数的本质——处理排列组合问题的有利工具,而不是简单的\(\frac{1}{1-x}\)的指标代换。因此这篇文章,我打算从最基本的排列组合问题写起,最后慢慢扩展到\(\frac{1}{1-x} = \sum_{i=0}^{\infty}x^i, e^x = \sum_{i=0}^{\infty} \frac{x^i}{i!}\)。内容会比较基础,高端玩家能够直接看鏼爷的集训队论文html

生成函数

定义

维基百科上是这么定义的:函数

在数学中,某个序列\((a_n)_{n \in \mathbb{N}}\) 的母函数(又称生成函数,英语:Generating function)是一种形式幂级数,其每一项的系数能够提供关于这个序列的信息。工具

讲的通俗一点,对于某个序列\({a_0, a_1, \dots, a_n}\),我想找一个函数来表示它,假设是\(G(x) = a_0 + a_1x + a_2x^2 \dots a_n x^n\)。这时候函数第\(i\)项的系数就表示了序列中的第\(i\)个元素。同时咱们也能够看到,函数中的自变量\(x\)好像并无什么意义,他的取值并不影响序列的表示,所以咱们称这种函数为形式幂级数学习

用处

那么这样定义由什么好处呢?spa

咱们仔细观察一下\(G(x)\),不难发现这是一个多项式函数,对于多项式咱们知道他有加、减、乘、除、求逆、取ln、exp等运算。那么咱们对\(G(x)\)进行乘法运算,也就是至关于对序列进行乘法运算,那么这样干有什么意义呢?咱们不妨从一个题目入手。code

普通生成函数

有三种物品,分别有\(3, 2, 3\)个,问拿出\(4\)个进行组合\((\{1123\}, \{3211\}\)算一种)的方案数是多少htm

学过dp的人可能会一眼看出是背包板子题。直接设\(f[i][j]\)表示当前到第\(i\)个位置,已经选了\(j\)个物品的方案数。转移的时候枚举一下当前选了几个blog

f[0][0] = 1;
for(int i = 1; i <= 3; i++) 
    for(int j = 0; j <= 8; j++) //当前总共要选出j个 
        for(int k = 0; k <= j; k++) //已经选了k个
            if(j - k <= v[i]) //此时要选j-k个
                f[i][j] += f[i - 1][k];

能够获得\(f[3]\)的系数为\(\{1\ 3\ 6\ 9\ 10\ 9\ 6\ 3\ 1 \}\)(从0开始编号),\(4\)最对应的一项是\(10\)教程

那用生成函数怎么作呢?

咱们能够对每一个物品构造一个多项式函数,其中第\(i\)项的系数\(a_i\)表示选了\(i\)个当前物品的方案数。

那么第一个物品的生成函数为\(G_1(x) = 1 + x^1 + x^2 + x^3\) (相同的物品选\(i\)个的方案数固然是1)

第二个物品的生成函数为\(G_2(x) = 1 + x^1 + x^2\)

第三个为\(G_3(x) = 1 + x^1 + x^2 + x^3\)

先说结论:最终答案是\(G_1(x) * G_2(x) * G_3(x)\)的第\(4\)项的系数

这是为何呢?考虑两个多项式相乘的结果\(f* g\),它的第\(k\)项的系数为\(\sum_{i=0}^k f_i g_{k-i}\)。这个过程是至关因而在枚举第一个物品选了几个,好比\(4\)这一项,他等于\(f_0g_4 + f_1g_3 + f_2 g_2 + f_3g_1 + f_4g_0\)

再具体一点,抛开刚刚那个题目中系数等于\(1\)的限制,咱们假设\(f_1 = 2, g_3 = 3\),也就是说从第一个物品中选出\(1\)个有两种方案,第二个物品中选出\(3\)个有三种方案,那么\(f_1 * g_3=2 * 3\)就至关于第一个物品的两种方案能够与第二个物品的三种方案任意组合来获得\(4\)种物品。(再看不懂的话建议去补一下高中组合计数qwq,这里讲的这么详细是为了给指数生成函数作铺垫)

这里建议你们去手玩一下多项式乘法,玩一下(玩的时候枚举\(x^i\)算他的系数)就会发现这个过程与背包的过程惊人的类似,由于事实上背包的过程就是在模拟多项式乘法。

这里为了下文(指数型生成函数)好讲解,本菜鸡直接把多项式相乘的结果(抄一下)写出来

\[ \begin{aligned} G(x) &= (1+x+x^2+x^3)(1+x+x^2)(1+x+x^2+x^3) \\ &= (1+2x+3x^2+3x^3+2x^4+x^5)(1+x+x^2+x^3)\\ &=1+3x+6x^2+9x^3+10x^4+9x^5+6x^6+3x^7+x^8 \end{aligned} \]

其中\(x^4\)项能够由下面这些获得,这种形式与咱们的手玩结果就很是类似了

\[x_1x_3^3+x_2x_3^3+x_1^2x_3^2+x_1x_2x_3^2+x_2^2x_3^2+x_1^3x_3+x_1^2x_2x_3+x_1x_2^2x_3+x_1^3x_3+x_1^2x_2^2\]

形如\(G(x) = \sum_{i=0}^n a_ix_i\)的表示一个序列的多项式函数,咱们称之为普通生成函数

讲到这里你须要大概明白:生成函数的基本概念,生成函数相乘的组合意义。

接下来按道理应该讲\(\frac{1}{1-x}\)及其运算,可是我想先介绍一下指数生成函数的基本概念。

指数生成函数

经过刚刚的讲解咱们不难看出,普通生成函数的意义在于解决组合类计数问题。可是别忘了组合的兄弟排列呀。指数生成函数就是用来解决排列类问题。

仍是刚刚的题目,咱们改一下限制

有三种物品,分别有\(3, 2, 3\)个,问拿出\(4\)个进行排列\((\{1123\}, \{3211\}\)算不一样方案)的方案数是多少(HDU1521)

这一类问题仅仅是比刚刚多了一个顺序的缘由,可是难度却比刚刚大了很多(背包也能够作,只要在转移的时候乘一个组合数便可,留给你们思考)

这里先介绍一下多重集排列数

\(S = \{a_1, a_2 \dots a_n\}, N = \sum_{i=1}^n a_i\),其中第\(a_i\)表示第\(i\)个物品有\(a_i\)个。
从中选出\(N\)个进行排列的方案数为\(\frac{N!}{a_1!a_2! \dots a_n!}\)
解释的话就是至关于任意排列以后减去同种物品之间多出来的方案

这样咱们就获得了一个思路:先把全部组合获得的方案算出来,而后再对每一种方案分别计算排列数,最后加起来。

好比咱们刚刚已经获得了组合的方案:

\[x_1x_3^3+x_2x_3^3+x_1^2x_3^2+x_1x_2x_3^2+x_2^2x_3^2+x_1^3x_3+x_1^2x_2x_3+x_1x_2^2x_3+x_1^3x_3+x_1^2x_2^2\]

其中\(x_1 x_3^3\)这一项的排列方案就是\(\frac{4!}{1!3!}\)\(x_1x_2x_3^2\)这一项的排列方案就是\(\frac{4!}{1!1!2!}\)。观察一下,全部方案的分子都是\(4!\),分母都是选出来的对应数量的阶乘。

因而咱们引进指数型生成函数

形如\(G(x) = \sum_{i=0}^n a_i \frac{x_i}{i!}\)的表示序列的多项式函数,咱们称之为指数生成函数。

同时咱们分别构造出\(G_1(x) = 1+\frac{x^1}{1} + \frac{x^2}{2!} + \frac{x^3}{3!}\)

\(G_2(x) = 1 + \frac{x^1}{1} + \frac{x^2}{2}\)

\(G_3(x) = 1 + \frac{x^1}{1} + \frac{x^2}{2!} + \frac{x^3}{3!}\)

这时候再计算一下\(G_1(x) * G_2(x) * G_3(x)\)

\[ \begin{aligned} G_e(x) &= (1 + \frac{x}{1!} + \frac{x^2}{2!} + \frac{x^3}{3!})(1+\frac{x}{1!} + \frac{x^2}{2!}) (1 + \frac{x}{1!} + \frac{x^2}{2!} + \frac{x^3}{3!})\\ &= (1+2x+2x^2+\frac{7}{6}x^3 + \frac{5}{12}x^4 + \frac{1}{12}x^5) (1+x+\frac{1}{2}x^2 + \frac{1}{6}x^3)\\ &=(1+3x + \frac{9}{2}x^2 + \frac{14}{3}x^3 + \frac{35}{12}x^4 + \frac{17}{12}x^5 + \frac{35}{72} x^6 + \frac{8}{72}x^7 + \frac{1}{71}x^8) \end{aligned} \]

这时候如何计算选出\(4\)个物品的答案呢?简单\(\frac{35}{12} * 4! = 70\)

可能你们不由思考,为何这么定义函数乘起来就是排列数呢?想想,由于咱们对每一个系数构造的\(\frac{1}{i!}\)就至关因而多重集排列数中的分母呀

好了,若是你到这里都看懂了的话,说明你已经对生成函数有个大概的了解了。可是不知道你们是否是和我有着一样的感受:生成函数好麻烦啊qwq。

那么有没有一套能够简化些运算的理论呢?

答案是:固然有了!(否则我问个毛线)。下面讲的内容能够会有些刺激,须要你们有必定的数学基础(其实只要高中知识就好了)

普通生成函数的推广

简单介绍

这个也不能叫推广吧,是我本身瞎起的名字。。。

在咱们刚刚的运算中出现了一个经常使用的函数\(G(x) = \sum_{i=0}^n x^i\),这个东西怎么化简呢?

结论:\(\sum_{i=0}^{\infty} x^i = \frac{1}{1-x}\)

可能你和当初一次见到这个式子的我同样,大概是这个表情

image

咱们来证实一下。

\(S = 1 + x + x^2 + \dots x^{\infty}\)

\(xS = x + x^2 + x^3 + \dots x^{\infty}\)

\(S - xS = 1\)

\(S = \frac{1}{1-x}\)

是否是证的完美无缺可是又十分扯淡?由于这玩意儿显然只有\(x^{\infty}\)收敛也就是\(x\in(-1, 1)\)时成立。其实在这里只要在\(x\in(-1, 1)\)成立就能够了,由于生成函数是形式幂级数,咱们并不关心\(x\)的具体取值

有了这个咱们能干什么呢?咱们能够对\(\frac{1}{1-x}\)变形来表示更多的序列,同时咱们知道了\(\frac{1}{1-x}\)对应序列的第\(i\)项的系数为\(1\),那么当咱们知道了某一个序列的生成函数以后咱们也能够把它变成相似于\(\frac{1}{1-x}\)的形式从而获得通项公式。

首先介绍一些简单的变换,建议你们手玩一下下面的生成函数的推广形式,好比把"乘\(2\)"换成"乘\(k\)"

  • \(x\)替换为\(-x\)\(\frac{1}{1+x} = {1, -1, 1, -1, \dots}\)

  • \(x\)替换为\(2x\)\(\ \frac{1}{1-2x} = {1, 2, 4, 8, 16, \dots}\)

  • \(x\)替换为\(x^2\), \(\ \ \ \frac{1}{1-x^2} = {1, 0, 1, 0, 1 \dots}\)

  • 将分子乘\(2\), \(\ \ \ \ \quad\frac{2}{1-x} = {2, 2, 2, 2, 2, \dots}\)

  • 将分子乘\(x^3\), \(\ \ \quad \frac{x^3}{1-x} \ = {0, 0, 0, 1, 1, 1, 1 \dots}\)

  • 求个导, \(\qquad \ \ \ \ \ \frac{1}{(1-x)^2} = {1, 2, 3, 4, 5} \dots\)

  • 再求一次, \(\quad \ \ \ \frac{2}{(1-x)^3} ={2 + 6 + 12 + 20 \dots}\)

问题来了,我若是知道了某一个数列的生成函数,怎么求它的通项公式呢?通常的思路就经过各类奇技淫巧往上面的几个生成函数转化。这里要提一下比较经常使用的广义二项式定理

\[\frac{1}{(1-x)^n} = \sum_{k=0}^{\infty} C_{n+k-1}^{k-1} x^k\]

咱们来经过两个例子来具体讲一下它的用处

求斐波那契数列通项公式

很是不不要脸的抄一下本身之前的博客

首先要知道斐波那契数列的递推式

\[f_i = f_{i-1} + f_{i - 2}\]

\[f_0 = f_1 = 1\]

那么推导一下

\(A = 1 + 1x + 2x^2 + 3x^3 + 5x^4 + 8x^5 \dots\)

根据递推式,咱们能够这样变化,显然有

\[ \begin{aligned} A = \ 1 + 1x + &2x^2 + 3x^3 + 5x^4 + 8x^5 \dots \\ xA = \ \ \qquad x + &1x^2 + 2x^3 + 3x^4 + 5x^5\dots \\ x^2A =\qquad \qquad &1x^2 + 1x^3 + 2x^4 + 3x^5 \dots \end{aligned} \]

那么能够获得一个方程\(A - xA - x^2A = 1\)

整理一下\(A =\frac{1}{1-x-x^2}\)

这样咱们就获得了斐波那契数列的生成函数,然而并无什么卵用,由于咱们不能直接经过观察看出每一项的系数。

如今考虑一下,咱们接下来能够干什么。咱们已经知道了\(\frac{1}{1-x}\)\(\frac{1}{1-kx}\)所表示的序列。接下来要干的固然是把\(\frac{1}{1-x-x^2}\)往上面的两个式子转化。

\(\frac{1}{1-x-x^2}\)这玩意儿下半部分是个一元二次方程,咱们能够配方

\[1-x-x^2 = (1-\phi_1x)(1-\phi_2x)\]

\[\phi_1 = \frac{1+\sqrt{5}}{2}, \phi_2 = \frac{1-\sqrt{5}}{2}\]

(解的时候能够直接把后面的式子拆开,把这两个式子对应项联立组成方程组, \(\phi_1 \phi_2\)的取值是能够反过来的)

这个时候咱们发现已经找到与\(\frac{1}{1-kx}\)的联系了,咱们能够把\(\frac{1}{(1-\phi_1 x)(1-\phi_2 x)}\)拆成求和的形式。能够裂一下项

原式变为\(\frac{a}{1-\phi_1x} + \frac{b}{1-\phi_2 x}\),而后再解一个方程\(a(1-\phi_2 x) + b(1-\phi_1x) = 1\)

解这个方程就没那么休闲了,这里咱们选择把\(x\)当作主元对方程进行变换

\[(a+b - 1) - x(a\phi_2 + b\phi_1) = 0 \]

这样就好处理了,只要列个二元一次方程组

\[ \begin{cases} a+b-1 = 0\\ a\phi_2 + b\phi_1 = 0 \end{cases} \]

解一下能够获得\(a = \frac{1}{\sqrt{5}} \phi_1, b = -\frac{1}{\sqrt{5}} \phi_2\)

带回去

\[A = \frac{\phi_1}{\sqrt{5}} \frac{1}{1-\phi_1x} - \frac{\phi_2}{\sqrt{5}} \frac{1}{1-\phi_2x}\]

那么第\(n\)项的公式为

\[A_n = \frac{1}{\sqrt{5}} ((\frac{1+\sqrt{5}}{2})^{n+1} - (\frac{1-\sqrt{5}}{2})^{n+1})\]

解决组合类问题

好比这种休闲板子题

至多为\(k\)就是\(\frac{1-x^{k+1}}{1-x}\)

\(k\)的倍数就是\(\frac{1}{1-x^k}\)

化简完了就只剩下一个\(\frac{1}{(1-x)^5}\)

这个东西能够直接广义二项式定理展开,而后交一发pypy2就过了。。

指数生成函数的推广

和上面的很相似,这里直接说结论

\[e^x = \sum_{i=0}^{\infty} \frac{x^i}{i!}\]

证实
考虑直接将\(e^x\)\(x_0 = 0\)处泰勒展开
由泰勒展开的公式\(f(x) = f(x_0) + \frac{f^1(x_0)}{1} (x-x_0) + \frac{f^2(x_0)}{2!} (x-x_0)^2 + \dots + \frac{f^n(x0)}{n} (x-x_0)^n \xi\) (\(f^n\)的意思是求\(n\)次导数)
能够直接获得。

一些经常使用变换

  • \(e^{-x} = 1 - \frac{x}{1} + \frac{x}{2!} -\frac{x}{3!} + \frac{x}{4!}\dots\)

  • \(\frac{e^x + e^{-x}}{2} = 1 + \frac{x^2}{2!} + \frac{x^4}{4!} + \frac{x^6}{6!}\dots\)

  • \(\frac{e^x - e^{-x}}{2} = \frac{x}{1} + \frac{x^3}{3!} + \frac{x^5}{5!} + \frac{x^7}{7!}\)

  • \(e^{kx} = 1 + \frac{kx}{1} + \frac{k^2x^2}{2!} + \frac{k^3x^3}{3!} + \frac{k^4x^4}{4!} \dots\)

一道简单的题目

长度为\(n\)的序列,用红黄蓝绿四种颜色染色,其中红黄只能是偶数,问方案数

\(n \leqslant 10^9\)

这道题就比较休闲了

任意的是\(e^x\),偶数的是\(\frac{e^x + e^{-x}}{2}\)

最后化完是\(\frac{e^{4x} + 2e^{2x}+1}{4} = \frac{4^n+2 * 2^{n+1}}{4}\)(\(\frac{1}{4}\))至关于常数项

直接快速幂就能够求

后记

本篇讲的是关于生成函数最基础的内容,千万不要认为本身看懂了上面的内容就生成函数了,充其量也就是了解而已。生成函数理论十分博大精深,我也只是略知皮毛。过几天可能会根据学习状况更一些生成函数与多项式运算的东西,敬请期待吧qwq

参考资料

生成函数-罗煜楚(版权缘由暂不开)

组合数学—母函数与递推——朱全民

母函数——维基百科

相关文章
相关标签/搜索