1. 母函数
1.1 母函数的定义
计数问题的结果一般可以表示为自然数集上的函数,比如组合数可以看成是关于的函数。孤立的通项公式很难发现数值之间的内在联系,从而丢失了结果的整体性。本节介绍一下欧拉提出的母函数思想,它是计数问题的一个基本工具。
你一定知道组合数其实是二项式的系数,换个角度想就是多项式中包含了整个数列。利用单个对象来表示多个离散的对象,即方便了表示,也保留了离散对象的整体性,这对讨论想必是有好处的。为此对数列,称幂级数(1)为其母函数(gernerating function)。
这里并不要求幂级数收敛,我们只需把它当成是一种代数定义。和普通多项式一样,可以在上面定义类似的相等、加法、数乘、乘法(不考虑它们的现实意义),可以证明这样的代数构成了一个整环。在抽象代数中已经证明了,多项式有逆的充要条件是。比如常用的,其中就是前者的逆。
这里例子让我们想起了泰勒展开式,应该怎样看待一个初等函数与它的泰勒级数之间的关系?这些初等函数(比如)并不属于代数系统,但却可以作为对应幂级数的“缩写”形式存在。对于这些初等函数在复数域函数上的运算结果,它的幂级数是否与原代数系统的相同?多项式整环中的运算是兼容复数域多项式的,所以这两者可以看成是等价的,因此在使用时,大可放心地使用幂级数和初等函数。而这一点也为问题解决带来了便捷,正是母函数思想的威力所在。
1.2 母函数的应用
母函数除了作为一个形式表示,还能有做什么?代数系统中为什么要讨论加法、乘法?加法的意义不言而喻,一个计数问题被分为多个个独立的情况,在求得每个情况的母函数后,整个问题的母函数自然就是母函数之和。这其实就是大家在高中熟悉的加法原理,只不过母函数中包含了所有的值。
还有一个就是所谓乘法原理:一个计数问题被分为多个步骤,每步的个数相乘便是整个计数值。乘法原理也可以用母函数表示,母函数相等后展开,其中的每一项就体现了乘法原理,当然合并同类项时就是加法原理。你可能已经发现,母函数乘法其实就是在帮你“自动”完成计数的“穷举法”,相比较技巧性强的方法,母函数更具一般性。
当然母函数也有应用场景的限制,问题的条件往往是多个变量的和为定值,而项表示变量取值时有种方法,母函数相乘后取项的系数便是计数值。还拿二项式为例,它表示从个互异对象中选出的个数。这里的变量就是每个对象被取的次数(只能是,母函数为),条件是变量和为。整个母函数是,其中的系数便是。
值得注意的是中包含了所有的所有值,它们被做为一个整体保存了下了,之间的关系也更便于讨论(下一篇阐述)。关于母函数在计数问题中的应用,我们将在下一篇中有更多的例子,这里先就此打住。
• 求证:边长为正整数周长为的三角形个数的母函数为。(提示:排序和差值)
2. 递推关系
2.1 递推关系的定义
有时候数列是以递推关系表达的,或者计数问题本身就适合用递推求解(比如经典的斐波那契数列),现在我们需要把递推式转化为显式表达式、或者表示出母函数。先来看定义,式(2)的所示的关系叫阶递推关系,显然数列由它的前项唯一确定,这项也称递推关系的初始条件。需要提醒的是,阶的意思是最多和个前序数列相关,但并不一定每一项都与个前序数列相关。反之,如果递推式不存在这样的有限整数,它被称为无穷阶递推关系。
举个简单的例子,大家都熟悉古老的汉诺塔(hanoi)游戏,把个圆盘按从大到小的顺序放在一根柱子上,要求保持上小下大的关系将圆盘全部移到另一根柱子上。经过分析,最小的移动步骤是这样的:先设法将上面个移动到第二根柱子,再将最大的盘移到第三根柱子,最后将那个圆盘也移到第三根柱子。这个过程显然有递推式,求解就很简单了。得到递推关系也许并不是一件容易的事,但这里我们不关心这一步,假定已经获得了递推式表达式,注意力集中在求解上。

2.2 线性递推关系
递推关系式千变万化,不可能有统一的解法,具体问题需要具体分析,大部分形式都不一定能求解。这里我们只研究几种常见递推式,并试图寻找各自一般的解法。首先比较简单的是一阶阶线性递推关系(3),为了消除首项系数,设,并设,则有。比较容易求得,最后得到,这里就不展开了。特别地,当为常数时,可以得到通项式(4),汉诺塔问题便可求解。
当线性递推关系上升到时,情况变得复杂,我们不妨从最简单的齐次线性常系数递推关系(式(5))看起。将递推关系的每个表达式按列写成矩阵(6),观察矩阵的每一行,它们含有完整的数列(除开始有限项)。这就启发我们把数列当整体看待,自然想到用母函数,为方便讨论,这里先假设有正的收敛域,后面得到表达式再回头验证。
因为第一行的母函数是其它行之和,综合考察每行母函数与的差别,不难得到,从而有式(7)。记为式(8),其中是的互异复根,它被称为递推式(5)的特征多项式。则易知式(7)的分母为,利用有理分式的知识可知,式(7)可以拆分为若干项之和(为常数)。再利用的泰勒展开式,容易知道项的系数为,其中阶为。
这其实就得到了的表达式(9),每个含有个待定系数,总共正好有个待定数,而它们可以有个初始条件确定。斐波那契数列的递推式就是典型的齐次递推关系,它的特征方程是,两个根为,将带入便得到斐波那契数列的通项公式(10)。
再来看线性常系数递推关系式(11),在给定初始条件时,它也有唯一解。对于这样的问题,先忽略初始条件说不定可以降低一些难度,针对递推式(11)的特点,说不定可以“目测”出一个解。注意到满足齐次递推式(5),故它们的解正好相差一个式(5)的解(两个初始条件的差作为式(5)的初始条件)。某个初始条件下式(11)的解被称为特解,它的通解则是式(12)。
2.3 卷积递推关系
最后来看一个虽然复杂但却极为常用的递推关系,先来看一个问题:将个和个排列开来,有多少中排法使得序列有意义?有意义是指:(1)一对括号是有意义的;(2)如果序列有意义,那么和也有意义。记有意义的排列数为,其中。第一个显然是,先找到和它配对的,则序列可以表示为。要使得排列有意义,必须都有意义,故容易有递推式(13)。
满足递推关系(13)的数列被称为卡特兰(Catalan)数列,这个递归关系会出现在许多问题中,这里再列举几个例子,推导思路非常相似(二分和递归),这里就不赘述了。
(1)乘法组合问题。对于乘法,添加括号使其形成不同的乘法顺序。
(2)进出栈序列。个数依次进栈,中途可以有数出栈,求进、出栈序列的个数。
(3)找钱问题。个人拿5元、个人拿10元排队买5元的东西,如何排队使得不需要提前准备零钱。
(4)数列个数问题:正整数列,其中。
(5)凸多边形的三角形分割。边凸多变形可以被条不交叉的对角线分成个三角形,讨论某一条边被划分的情况。
(6)Dyck路计数。从格点走到,每步只能走向右上或右下方向最近的格点,且不能到达轴下方。

对于和式,在数学中非常常见,比如说级数相乘的柯西乘积。往往被称为向量和的卷积(Convolution,或柯西乘积),它是向量乘积的一种定义。回顾级数的柯西乘积,我们觉得这里用母函数处理也许会比较好。为此设卡特兰数列的母函数为,还是先假定它有正收敛域。
利用级数的柯西乘积,容易有,解得。展开的幂级数,并根据数列为正可得到卡特兰数列(14)。
上面两个例子充分展示了母函数在求解递推关系中的威力,观察递推关系的特点,列出母函数的方程,便可以很快得到母函数,更甚者可以得到数列通项。请尝试解决以下二元递推关系:
• ,已知。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架