Catalan数

Catalan(卡特兰)数

卡特兰数,又称卡塔兰数,是组合数学中一种常出现于各种计数问题中的数列。以比利时的数学家欧仁·查理·卡塔兰 (1814–1894)的名字来命名。1730年左右被蒙古族数学家明安图 (1692-1763)使用于对三角函数幂级数的推导而首次发现,1774年被发表在《割圜密率捷法》。
——百度百科

基本概念

引入

首先我们想这么一个问题:

对于一个 n × n n \times n n×n的一个矩形方格,连接其副对角线。

一个 B u g Bug Bug(虫子)现在处在左下角,每次只能向上或向右移动一格,且不能越过蓝线,问有多少种不同的路径?

网格

首先如果不考了蓝线,根据曼哈顿距离原理可知,任意一个路径都可写成是一个只有“上”和“右”的序列,例如:上上右上右…。其长度为 2 n 2n 2n,分别有 n n n个上和 n n n个右,所以总的方案数为 C 2 n n C_{2n}^{n} C2nn,即在 2 n 2n 2n个位置上选 n n n个位置放上或右。

然后,对于每一个不符合要求的路径(绿线),其必定会有一个点与直线 y = x + 1 y=x+1 y=x+1相交(橙线),如上图的点 P P P,我们把直线 y = P y y=P_{y} y=Py以上的部分做关于直线 y = x + 1 y=x+1 y=x+1的对称(蓝色虚线),这时候的终点变成了 ( n − 1 , n + 1 ) (n-1,n+1) (n1,n+1),即对于问题从 ( 0 , 0 ) (0,0) (0,0)点到 ( n − 1 , n + 1 ) (n-1,n+1) (n1,n+1)点只能向右走或向上走的路径数,答案是 C 2 n n + 1 C_{2n}^{n+1} C2nn+1 C 2 n n − 1 C_{2n}^{n-1} C2nn1

最终我们得到答案是:

C 2 n n − C 2 n n + 1 C_{2n}^{n} - C_{2n}^{n+1} C2nnC2nn+1

也可以写成是:

C 2 n n − C 2 n n − 1 C_{2n}^{n} - C_{2n}^{n-1} C2nnC2nn1

因为 C 2 n n + 1 = C 2 n n − 1 C_{2n}^{n+1} = C_{2n}^{n-1} C2nn+1=C2nn1

Catalan的通项公式

这就是 C a t a l a n Catalan Catalan数列的原始定义。即:

C ( n ) = C 2 n n − C 2 n n + 1 C(n) = C_{2n}^{n} - C_{2n}^{n+1} C(n)=C2nnC2nn+1

对组合数进行化简(不要被算式吓到,就是一个通分化简的过程):

C ( n ) = C 2 n n − C 2 n n + 1 = ( 2 n ) ! n ! n ! − ( 2 n ) ! ( n + 1 ) ! ( n − 1 ) ! = 1 n + 1 ( ( 2 n ) ! ( n + 1 ) n ! n ! − ( 2 n ) ! n ! ( n − 1 ) ! ) = 1 n + 1 ( ( 2 n ) ! ( n + 1 ) n ! n ! − ( 2 n ) ! n n ! n ! ) = 1 n + 1 ( ( 2 n ) ! ( n + 1 ) − ( 2 n ) ! n n ! n ! ) = 1 n + 1 ( ( 2 n ) ! n ! n ! ) = 1 n + 1 C 2 n n C(n) = C_{2n}^{n} - C_{2n}^{n+1} \\ = \frac{(2n)!}{n!n!} - \frac{(2n)!}{(n+1)!(n-1)!} \\ = \frac{1}{n+1}( \frac{(2n)!(n+1)}{n!n!} - \frac{(2n)!}{n!(n-1)!} ) \\ = \frac{1}{n+1}( \frac{(2n)!(n+1)}{n!n!} - \frac{(2n)!n}{n!n!} ) \\ = \frac{1}{n+1}( \frac{(2n)!(n+1) - (2n)!n}{n!n!} ) \\ = \frac{1}{n+1}( \frac{(2n)!}{n!n!} ) \\ = \frac{1}{n+1}C_{2n}^{n} \\ C(n)=C2nnC2nn+1=n!n!(2n)!(n+1)!(n1)!(2n)!=n+11(n!n!(2n)!(n+1)n!(n1)!(2n)!)=n+11(n!n!(2n)!(n+1)n!n!(2n)!n)=n+11(n!n!(2n)!(n+1)(2n)!n)=n+11(n!n!(2n)!)=n+11C2nn

因此我们有 C a t a l a n Catalan Catalan数列的通项公式

C ( n ) = 1 n + 1 C 2 n n C(n) = \frac{1}{n+1}C_{2n}^{n} C(n)=n+11C2nn

解释:

  • 为了构造 n n n对合法的括号序列,我们先通过 ( 2 n n ) \binom{2n}{n} (n2n)种方法去填充"(“或者”)",然后再减去不符合条件的情况。每一种不符合条件的情况,都有存在一个最短前缀,使得右括号的数量=左括号的数量+1,我们这个前缀的每一个括号,那么就会得到一个左括号数量=右括号数量+1的括号序列且唯一对应,方案数为 ( 2 n n + 1 ) \binom{2n}{n+1} (n+12n),即为 ( 2 n n ) − ( 2 n n + 1 ) = 1 n + 1 ( 2 n n ) \binom{2n}{n} -\binom{2n}{n + 1} = \frac{1}{n+1}\binom{2n}{n} (n2n)(n+12n)=n+11(n2n)

Catalan的递推公式

构造递推公式要把 C ( n ) C(n) C(n) C ( n − 1 ) C(n-1) C(n1)联系起来,因此:

C ( n ) = 1 n + 1 C 2 n n C ( n − 1 ) = 1 n C 2 n − 2 n − 1 C(n) = \frac{1}{n+1}C_{2n}^{n} \\ C(n-1) = \frac{1}{n}C_{2n - 2}^{n-1} C(n)=n+11C2nnC(n1)=n1C2n2n1

打开:

C ( n ) = 1 n + 1 ( ( 2 n ) ! n ! n ! ) C ( n − 1 ) = 1 n ( ( 2 n − 2 ) ! ( n − 1 ) ! ( n − 1 ) ! ) C(n) = \frac{1}{n+1} ( \frac{(2n)!}{n!n!} )\\ C(n-1) = \frac{1}{n}( \frac{(2n-2)!}{(n-1)!(n-1)!} ) C(n)=n+11(n!n!(2n)!)C(n1)=n1((n1)!(n1)!(2n2)!)

所以:

C ( n ) = 4 n − 2 n + 1 C ( n − 1 ) C(n) = \frac{4n-2}{n+1} C(n-1) C(n)=n+14n2C(n1)

Catalan的计数公式

C ( n ) = ∑ i = 0 n − 1 C ( i ) ⋅ C ( n − 1 − i ) C(n) = \sum_{i=0}^{n-1}C(i) \cdot C(n-1-i) C(n)=i=0n1C(i)C(n1i)

解释:

  • 为了构造 n n n对合法括号序列,其序列第一项一定是"(",那么我们枚举第一项"(“对应的”)“的位置,在第一对”()“中有 i i i对合法的序列,在第一对”()"外有 n − i − 1 n-i-1 ni1对合法的序列,我们枚举 i i i 0 0 0 n − 1 n-1 n1,求和累加得到上述式子。
  • 考虑 n n n个元素的出入栈次序问题,第一个入栈的元素可以在第 1 , 2 , 3 , 4 , … , n − 1 1,2,3,4,\ldots,n-1 1,2,3,4,,n1处出栈,那么我们枚举其前后的元素个数递归即可。

上述是 C a t a l a n Catalan Catalan数列的常用几个公式,下面给出 C a t a l a n Catalan Catalan数列前 10 10 10项,接下来讲解实际的问题。

C ( 0 ) = 1 C ( 1 ) = 1 C ( 2 ) = 2 C ( 3 ) = 5 C ( 4 ) = 14 C ( 5 ) = 42 C ( 6 ) = 132 C ( 7 ) = 429 C ( 8 ) = 1430 C ( 9 ) = 4862 C ( 10 ) = 16796 C(0)=1 \\ C(1)=1 \\ C(2)=2 \\ C(3)=5 \\ C(4)=14 \\ C(5)=42 \\ C(6)=132 \\ C(7)=429 \\ C(8)=1430 \\ C(9)=4862 \\ C(10)=16796 C(0)=1C(1)=1C(2)=2C(3)=5C(4)=14C(5)=42C(6)=132C(7)=429C(8)=1430C(9)=4862C(10)=16796

实际问题

出栈次序问题

P1044

对于一个序列,栈的大小大于序列的大小,问不同的出栈序列有几个?

例如序列: 123456 123456 123456。设序列长度为 n n n的答案数为 C ( n ) C(n) C(n)

  1. 首先栈里面没有元素,我们只能把 6 6 6入栈。
  2. 接下来我们不管栈顶元素 6 6 6,把栈看成是一个空栈,面对序列 12345 12345 12345,又是一个子问题。
  3. 在我们处理子问题的时候,我们考虑 6 6 6什么时候出栈?
  4. 元素 6 6 6可以在 12345 12345 12345都处理完毕之后出栈,此时的数量为 C ( 5 ) C(5) C(5);也可以在 1 1 1 2345 2345 2345之间出栈,此时的数量为 C ( 1 ) × C ( 4 ) C(1) \times C(4) C(1)×C(4);同理,剩下的数量分别为 C ( 2 ) × C ( 3 ) C(2) \times C(3) C(2)×C(3) C ( 3 ) × C ( 2 ) C(3) \times C(2) C(3)×C(2) C ( 4 ) × C ( 1 ) C(4) \times C(1) C(4)×C(1) C ( 5 ) C(5) C(5)
  5. 把这些不同情况的数量进行加和,可以发现 C ( n ) C(n) C(n)就是 C a t a l a n Catalan Catalan数列,我们推导的方法就是 C a t a l a n Catalan Catalan数列的计数公式。
int dp[19];

int main()
{
    int n;
    cin >> n;
    dp[0] = dp[1] = 1;

    for(int i = 2;i<=n;i++)
    {
        for(int k = 0;k<=i-1;k++)
        {
            dp[i] += dp[k] * dp[i-1-k];
        }
    }
    cout << dp[i];
    return 0;
}

n个节点的不同形态的二叉树的数量

n n n个节点的不同形态的二叉树的数量是多少呢?设答案为 C ( n ) C(n) C(n)

选定根节点之后,还剩 n − 1 n-1 n1个节点可以放置,只考虑左子树,左子树可以有 0 0 0 1 1 1一直到 n − 1 n-1 n1个节点,右子树用 n − 1 n-1 n1减去左子树的节点数即可。因此可以得到公式:

C ( n ) = ∑ i = 0 n − 1 C ( i ) ⋅ C ( n − 1 − i ) C(n) = \sum_{i=0}^{n-1}C(i) \cdot C(n-1-i) C(n)=i=0n1C(i)C(n1i)

发现 C ( n ) C(n) C(n)就是 C a t a l a n Catalan Catalan数列。

同理LeetCode 96 不同的二叉搜索树

考虑 1 , 2 , 3 , 4 , … , n 1,2,3,4,\ldots,n 1,2,3,4,,n分别当根节点的情况,其答案还是 C a t a l a n Catalan Catalan数列。

n个节点的不同形态的树的数量

我们根据树与二叉树“左儿子右兄弟”的对应法则,每一种 n n n个节点形态的树,都对应一种 n − 1 n-1 n1个节点的二叉树的形态,因此答案为 C n − 1 C_{n-1} Cn1

从左下角走到右上角不穿过副对角线的方案数

即开篇的问题,可以理解为向左走就是入栈,向上走就是出栈,等价与出栈次序问题。这也给定了出栈次序问题的一个几何解释,连接了计数公式和通项公式的桥梁。

合理的括号序列问题

给定 n n n个括号"()",问有几种合理的括号序列问题。例如 n = 2 n=2 n=2的时候,"(())“和”()()“就是合法的,像”))(("就是不合法的。同理与出栈次序问题,添加一个左括号相当于入栈,添加一个右括号相当于出栈。

凸n边形的三角形划分方案数

我们知道,给定一个凸n边形,可以用 n − 3 n-3 n3条线段把这个多边形划分成 n − 2 n-2 n2个三角形,其中线段的顶点是多边形的顶点,线段不能交叉。

我们任意选取一个顶点设为 1 1 1,然后按照顺时针或者逆时针的顺序给顶点编号,与 1 1 1相邻的顶点是 n n n 2 2 2,选取 1 1 1 n n n剩下的顶点为 2 , 3 , … , n − 1 2,3,\ldots,n-1 2,3,,n1,在剩下的顶点中选取一个顶点当做是 k k k,那么令 1 → k → 1 1 \to k \to 1 1k1的区域为 A A A i , k , n i,k,n i,k,n这是个三角形, k → n → k k \to n \to k knk这个区域为区域 B B B,那么分别把区域 A A A,和 B B B看成是子问题,发现仍然是 C a t a l a n Catalan Catalan数列。

例题

P2532

普通卡特兰计数,需要高精度。

总结

基本关于 C a t a l a n Catalan Catalan数列的相关问题就这些了,我们发现,基本大多数问题都可以转换成出栈次序问题,所以我们掌握了出栈次序问题的思考方式,我们也就掌握了 C a t a l a n Catalan Catalan数列相关计数问题的思考方式。

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值