Skip to content

卡特兰数 学习笔记

Catalan 数列

Catalan 数列 Hn 可以应用于以下问题:

  1. 2n 个人排成一行进入剧场。入场费 5 元。其中只有 n 个人有一张 5 元钞票,另外 n 人只有 10 元钞票,剧院无其它钞票,问有多少种方法使得只要有 10 元的人买票,售票处就有 5 元的钞票找零?
  2. 有一个大小为 n×n 的方格图左下角为 (0,0) 右上角为 (n,n),从左下角开始每次都只能向右或者向上走一单位,不走到对角线 y=x 上方(但可以触碰)的情况下到达右上角有多少可能的路径?
  3. 在圆上选择 2n 个点,将这些点成对连接起来使得所得到的 n 条线段不相交的方法数?
  4. 对角线不相交的情况下,将一个凸多边形区域分成三角形区域的方法数?
  5. 一个栈(无穷大)的进栈序列为 1,2,3,,n 有多少个不同的出栈序列?
  6. n 个结点可构造多少个不同的二叉树?
  7. n+1n1 组成的 2n 个数 a1,a2,,a2n,其部分和满足 a1+a2++ak0 (k=1,2,3,,2n),有多少个满足条件的数列?

其对应的序列为:

H0H1H2H3H4H5H6...
11251442132...

递推式

该递推关系的解为:

Hn=(2nn)n+1(n2,nN+)

关于 Catalan 数的常见公式:

Hn={i=0n1HiHn1in2,nN+1n=0,1Hn=Hn1(4n2)n+1Hn=(2nn)(2nn1)

例题 洛谷 P1044 栈

题目大意
  • 入栈顺序为 1,2,,n,求所有可能的出栈顺序的总数。
cpp
#include <iostream>
using namespace std;
int n;
long long f[25];

int main() {
    f[0] = 1;
    cin >> n;
    for (int i = 1; i <= n; i++)
        f[i] = f[i - 1] * (4 * i - 2) / (i + 1);
    // 这里用的是常见公式2
    cout << f[n] << endl;
    return 0;
}

封闭形式

卡特兰数的递推式为

Hn=i=0n1HiHni1(n2)

其中 H0=1,H1=1。设它的普通生成函数为 H(x)

我们发现卡特兰数的递推式与卷积的形式很相似,因此我们用卷积来构造关于 H(x) 的方程:

H(x)=n0Hnxn=1+n1i=0n1HixiHni1xni1x=1+xi0Hixin0Hnxn=1+xH2(x)

解得

H(x)=1±14x2x

那么这就产生了一个问题:我们应该取哪一个根呢?我们将其分子有理化:

H(x)=2114x

代入 x=0,我们得到的是 H(x) 的常数项,也就是 H0。当 H(x)=21+14x 的时候有 H(0)=1,满足要求。而另一个解会出现分母为 0 的情况(不收敛舍弃。

因此我们得到了卡特兰数生成函数的封闭形式:

H(x)=114x2x

接下来我们要将其展开。但注意到它的分母不是斐波那契数列那样的多项式形式,因此不方便套用等比数列的展开形式。在这里我们需要使用牛顿二项式定理。我们来先展开 14x

(1)(14x)12=n0(12n)(4x)n=1+n1(12)nn!(4x)n

注意到

(12)n=121232(2n3)2=(1)n1(2n3)!!2n=(1)n1(2n2)!2n(2n2)!!=(1)n1(2n2)!22n1(n1)!

这里使用了双阶乘的化简技巧。那么带回 (1) 得到

(14x)12=1+n1(1)n1(2n2)!22n1(n1)!n!(4x)n=1n1(2n2)!(n1)!n!2xn=1n1(2n1n)1(2n1)2xn

带回原式得到

H(x)=114x2x=12xn1(2n1n)1(2n1)2xn=n1(2n1n)1(2n1)xn1=n0(2n+1n+1)1(2n+1)xn=n0(2nn)1n+1xn

这样我们就得到了卡特兰数的通项公式。

路径计数问题

非降路径是指只能向上或向右走的路径。

  1. (0,0)(m,n) 的非降路径数等于 mxny 的排列数,即 (n+mm)

  2. (0,0)(n,n) 的除端点外不接触直线 y=x 的非降路径数:

    先考虑 y=x 下方的路径,都是从 (0,0) 出发,经过 (1,0)(n,n1)(n,n),可以看做是 (1,0)(n,n1) 不接触 y=x 的非降路径数。

    所有的的非降路径有 (2n2n1) 条。对于这里面任意一条接触了 y=x 的路径,可以把它最后离开这条线的点到 (1,0) 之间的部分关于 y=x 对称变换,就得到从 (0,1)(n,n1) 的一条非降路径。反之也成立。从而 y=x 下方的非降路径数是 (2n2n1)(2n2n)。根据对称性可知所求答案为 2(2n2n1)2(2n2n)

  3. (0,0)(n,n) 的除端点外不穿过直线 y=x 的非降路径数:

    用类似的方法可以得到:2n+1(2nn)