很多计数问题给得出递推关系(第 k+1 项由前面项决定)却看不出通项:斐波那契、卡特兰数、汉诺塔。本章给两套把递推变成公式的机器:特征方程(线性递推的直通车)与生成函数(把数列编码成多项式,用代数操作解计数问题)。生成函数是组合数学的「终极武器」,也是数据结构课第 10 章(动态规划优化)与算法课(平均复杂度分析)的数学后盾。
回顾两个老朋友(第 7 章):
线性常系数齐次递推的标准形:aₙ = c₁aₙ₋₁ + … + cₖaₙ₋ₖ。解法三步:写出特征方程 rᵏ = c₁rᵏ⁻¹ + … + cₖ,求根,按根组装通项。
斐波那契的特征方程:r² = r + 1,即 r² − r − 1 = 0,两根 r = (1±√5)/2(黄金比 φ ≈ 1.618 与其孪生)。通项(比内公式):
验证 F(0) = 0、F(1) = 1(代入即证),归纳可证对所有 n 成立(第 4 章)。几个推论:φⁿ/√5 主导,所以 F(n) ≈ φⁿ/√5,斐波那契相邻项之比趋于黄金比;F(n) 是 Θ(φⁿ)——指数级(数据结构课第 9 章「朴素递归为什么爆炸」的精确答案)。
特征方程的原理一句话:猜 aₙ = rⁿ 形式的解,代入递推得 r² = r + 1——「指数解自动满足线性递推」。重根情形(如 aₙ = 2aₙ₋₁ − aₙ₋₁):通项加一项 n·rⁿ(r 重根的补票),练习里实算。
普通生成函数:数列 a₀, a₁, a₂… 编码为幂级数 G(x) = a₀ + a₁x + a₂x² + …。编码的目的:把「对数列的操作」变成「对多项式的操作」:
| 数列操作 | 生成函数操作 |
|---|---|
| 整体右移一位(补 0) | 乘 x |
| 相邻项相加合并 | 两个 G(x) 相加 |
| 卷积 cₙ = Σ aᵢbₙ₋ᵢ | 相乘 G(x)·H(x) |
| 部分和 sₙ = Σaᵢ | 除以 (1−x) |
几何级数是最重要的样本:1, 1, 1, … 的生成函数是 1/(1+x²)?不,是 1/(1−x)(|x| 小于 1 时收敛;形式幂级数视角下连收敛都不需要,纯代数对象)。由此得:序列 0, 1, 2, 3… 的 GF 是 x/(1−x)²,序列 1, 2, 4, 8… 是 1/(1−2x)——分母 (1−cx) 对应等比,分母的重数对应多项式因子,与 10.2 的特征方程互为表里(特征根 r ↔ 分母因子 (1−rx))。
演示一:斐波那契的生成函数。G(x) = F₀ + F₁x + F₂x² + …,利用递推 Fₙ = Fₙ₋₁ + Fₙ₋₂ 乘 xⁿ 求和整理:
部分分式分解后按等比级数展开,系数即比内公式——同一个答案,另一条更机械的路(机械意味着可自动化,计算机代数系统就这么解)。
演示二:卡特兰数(第 7 章)。递推 Cₙ = Σᵢ CᵢCₙ₋₁₋ᵢ(n ≥ 1),C₀ = 1。右边的求和恰是「GF 自乘后取 xⁿ 系数」,翻译成 GF 方程:
解二次方程(取正解):C(x) = (1 − √(1−4x))/(2x),展开得:
递推 → 代数方程 → 闭式,计数问题的三段流水。括号匹配、出栈序列、二叉树(第 7 章的「殊途同归」)在此获得统一的解法。
三处直接变现:算法平均复杂度分析(quickSort 的比较次数递推 → 生成函数/级数求和,得出 2n ln n,算法课的经典推导);DP 的优化(数据结构课第 10 章:递推的 GF 视角常揭示「可卷积」结构,分治 FFT 加速);递归式的自动求解(Mathematica/Sympy 的 rsolve 就是特征方程与 GF 的程序化)。以及一个方法论层面的收获:「难解的递推」往往缺一个「对的坐标系」,生成函数就是把数列搬到多项式坐标系的重定位操作,和第 6 章把城市搬进图、第 8 章把对称搬进群,是同一种数学行为。