卡特兰数详解

介绍

这是一类组合数问题的计算方法,在省选等各大考场中身影频现。

这类组合数问题可以千变万化,各种扩展,所以,作为一名合格的OIer,是不能不学这个优秀的东西的。

柿子们

首先摆一下卡特兰数的计算公式:

递推式: h ( n + 1 ) = ∑ i = 0 n h ( i ) h ( n − i ) h(n+1)=\sum\limits_{i=0}^n h(i)h(n-i) h(n+1)=i=0nh(i)h(ni)

通项公式1: h ( n ) = C 2 n n / ( n + 1 ) h(n)=C_{2n}^{n} /(n+1) h(n)=C2nn/(n+1)

通项公式2: h ( n ) = C 2 n n − C 2 n n + 1 h(n)=C_{2n}^{n} - C_{2n}^{n+1} h(n)=C2nnC2nn+1

其实通项公式 2 2 2 稍稍转化就能变成通项公式 1 1 1,像这样:
C 2 n n − C 2 n n + 1 = ( 2 n ) ! n ! n ! − ( 2 n ) ! ( n − 1 ) ! ( n + 1 ) ! = ( 2 n ) ! ( n − 1 ) ! ( n + 1 ) ! − ( 2 n ) ! n ! n ! n ! n ! ( n − 1 ) ! ( n + 1 ) ! = ( 2 n ) ! ( ( n − 1 ) ! ( n + 1 ) ! − n ! n ! ) n ! n ! ( n − 1 ) ! ( n + 1 ) ! = ( 2 n ) ! ( ( n + 1 ) ! − n × n ! ) n ! n ! ( n + 1 ) ! = ( 2 n ) ! ( ( n + 1 ) ! − n × n ! ) n ! n ! n ! / ( n + 1 ) = ( 2 n ) ! ( ( n + 1 ) − n ) n ! n ! / ( n + 1 ) = ( 2 n ) ! n ! n ! / ( n + 1 ) = C 2 n n / ( n + 1 ) \begin{aligned} C_{2n}^n - C_{2n}^{n+1}&=\frac {(2n)!} {n!n!} -\frac {(2n)!} {(n-1)!(n+1)!}\\ &=\frac {(2n)!(n-1)!(n+1)!-(2n)!n!n!} {n!n!(n-1)!(n+1)!}\\ &=\frac {(2n)!((n-1)!(n+1)!-n!n!)} {n!n!(n-1)!(n+1)!}\\ &=\frac {(2n)!((n+1)!-n\times n!)} {n!n!(n+1)!}\\ &=\frac {(2n)!((n+1)!-n\times n!)} {n!n!n!} /(n+1)\\ &=\frac {(2n)!((n+1)-n)} {n!n!} /(n+1)\\ &=\frac {(2n)!} {n!n!} /(n+1)\\ &=C_{2n}^n /(n+1)\\ \end{aligned} C2nnC2nn+1=n!n!(2n)!(n1)!(n+1)!(2n)!=n!n!(n1)!(n+1)!(2n)!(n1)!(n+1)!(2n)!n!n!=n!n!(n1)!(n+1)!(2n)!((n1)!(n+1)!n!n!)=n!n!(n+1)!(2n)!((n+1)!n×n!)=n!n!n!(2n)!((n+1)!n×n!)/(n+1)=n!n!(2n)!((n+1)n)/(n+1)=n!n!(2n)!/(n+1)=C2nn/(n+1)

稍稍转化(大雾 稍微还是有那么点长的……

通项公式3: h ( n ) = h ( n − 1 ) × ( 4 n − 2 ) n + 1 h(n)=\frac {h(n-1)\times(4n-2)} {n+1} h(n)=n+1h(n1)×(4n2)

这个也是大力推一推就能变成通项公式1
h ( n − 1 ) × ( 4 n − 2 ) n + 1 = C 2 n − 2 n − 1 × ( 4 n − 2 ) n ( n + 1 ) = ( 2 n − 2 ) ! ( n − 1 ) ! ( n − 1 ) ! × ( 4 n − 2 ) n + 1 = ( 2 n − 2 ) ! × n × n ( n − 1 ) ! ( n − 1 ) ! × n × n × ( 4 n − 2 ) n ( n + 1 ) = ( 2 n − 2 ) ! × n × n × 2 ( 2 n − 1 ) n ! n ! ( n + 1 ) n = ( 2 n − 2 ) ! × n × 2 n × ( 2 n − 1 ) n ! n ! ( n + 1 ) n = ( 2 n ) ! n ! n ! ( n + 1 ) \begin{aligned} \frac {h(n-1)\times(4n-2)} {n+1}&=\frac {C_{2n-2}^{n-1} \times (4n-2)} {n(n+1)}\\ &=\frac {(2n-2)!} {(n-1)!(n-1)!} \times \frac {(4n-2)} {n+1}\\ &=\frac {(2n-2)! \times n \times n} {(n-1)!(n-1)! \times n \times n} \times \frac {(4n-2)} {n(n+1)}\\ &=\frac {(2n-2)! \times n \times n \times 2(2n-1)} {n!n!(n+1)n}\\ &=\frac {(2n-2)! \times n \times 2n \times (2n-1)} {n!n!(n+1)n}\\ &=\frac {(2n)!} {n!n!(n+1)} \end{aligned} n+1h(n1)×(4n2)=n(n+1)C2n2n1×(4n2)=(n1)!(n1)!(2n2)!×n+1(4n2)=(n1)!(n1)!×n×n(2n2)!×n×n×n(n+1)(4n2)=n!n!(n+1)n(2n2)!×n×n×2(2n1)=n!n!(n+1)n(2n2)!×n×2n×(2n1)=n!n!(n+1)(2n)!

时间复杂度

递推式: O ( n 2 ) O(n^2) O(n2)

通项公式1、2: O ( n ) O(n) O(n)

通项公式3: O ( n ) O(n) O(n)

特点

递推式: 做题推柿子一般用到它。(这个下面就会有体现了)

通项公式1、2: 一般在写代码的时候会选择用这个公式去求卡特兰数。

通项公式3: 可能它来到这个世界只是用来充数的。(如果有人知道这有什么用还请告诉一下qwq)

应用

应用真的是数不胜数,这里举几个十分经典的吧。

1.1 1.1 1.1

这个应该说是卡特兰数最经典的例题了。

有一个无限大的栈,现在 1 1 1 ~ n n n 依次进栈,随机出栈。问有多少种出栈顺序。
比如说, n n n 等于 3 3 3 时, 1 1 1 进栈, 2 2 2 进栈, 2 2 2 出栈, 3 3 3 进栈, 3 3 3 出栈, 1 1 1 出栈,那么出栈顺序就是 2 , 3 , 1 2,3,1 2,3,1,这就是当 n = 3 n=3 n=3 时的方案之一。

我们假设 i i i 是最后出栈的那个数。

在他前面,有 1 1 1 ~ i − 1 i-1 i1 这些数需要完成全部进栈和全部出栈,这样 i i i 才能压到栈底,成为最后出栈的数,那么方案数就是 h ( i − 1 ) h(i-1) h(i1)

在它后面,有 i + 1 i+1 i+1 ~ n n n 这些数需要完成全部进栈和全部出栈,这样当 i i i 出栈时才能成为最后出栈的那个数,方案数为 h ( n − i + 1 ) h(n-i+1) h(ni+1)

那么答案就是 h ( n ) = ∑ i = 1 n h ( i − 1 ) h ( n − i ) = ∑ i = 0 n − 1 h ( i ) h ( n − i − 1 ) h(n)=\sum_{i=1}^n h(i-1)h(n-i)=\sum_{i=0}^{n-1}h(i)h(n-i-1) h(n)=i=1nh(i1)h(ni)=i=0n1h(i)h(ni1)

变换一下就是 h ( n + 1 ) = ∑ i = 0 n h ( i ) h ( n − i ) h(n+1)=\sum_{i=0}^n h(i)h(n-i) h(n+1)=i=0nh(i)h(ni),也就是卡特兰数递推式

这就是为什么上面说:做题推柿子一般用到它

1.2 1.2 1.2

这个进栈问题有很多的变种,稍微列举一下。

01序列问题: 你现在有 n n n 0 0 0 n n n 1 1 1,用他们来组成一个长度为 2 n 2n 2n 的序列,要求这个序列的任意一个前缀中 1 1 1 的数量大于等于 0 0 0 的数量。

1 1 1 看做一次进栈, 0 0 0 看做一次出栈,任意前缀中 1 1 1 的数量大于等于 0 0 0 的数量等价于不能在栈为空时进行出栈操作,那么就完全等价于上面的进出栈问题了。

多边形分割问题: 你有一个凸 n n n 边形,你可以将这个 n n n 边形的顶点进行连接 n − 2 n-2 n2 次,将这个 n n n 边形分成 n − 2 n-2 n2 个三角形,问有多少种分法。

不妨将节点逆时针依次编号为 1 , 2 , 3 , . . . 1,2,3,... 1,2,3,... 号。当 1 1 1 号顶点向 i i i 号节点连边时,这个 n n n 边形被分成了一个 i i i 边形和一个 n − i + 2 n-i+2 ni+2 边形,这是两个子问题,我们设 n n n 边形的分法为 f [ n ] f[n] f[n],那么这两个子问题的分法就是 f [ i ] f[i] f[i] f [ n − i + 2 ] f[n-i+2] f[ni+2],乘起来就是一号节点向 i i i 号节点连边后的方案数。那么有:
f [ n ] = ∑ i = 3 n − 1 f [ i ] f [ n − i + 2 ] f[n]=\sum_{i=3}^{n-1} f[i]f[n-i+2] f[n]=i=3n1f[i]f[ni+2]

不妨设 g [ i ] = f [ i + 3 ] g[i]=f[i+3] g[i]=f[i+3],那么有:
g [ n − 3 ] = ∑ i = 3 n − 1 g [ i − 3 ] g [ n − i − 1 ] g[n-3]=\sum_{i=3}^{n-1} g[i-3]g[n-i-1] g[n3]=i=3n1g[i3]g[ni1]

发现这就是一个赤裸裸的卡特兰数了。

排队问题: 现在有 2 n 2n 2n 个人, n n n 个人手里有 5 5 5 元, n n n 个人手里有 10 10 10 元,他们都要买一个 5 5 5 元的东西,一开始老板没有零钱,问有多少种排队方法可以使得老板不会没钱找。

5 5 5 元看做进栈, 10 10 10 元看成出栈即可。

括号问题: 你有 n n n 对括号,即 n n n 个左括号, n n n 个右括号,问这些括号有多少种合理的排列方式。

把左括号看做进栈,右括号看做出栈即可。


2 2 2

n n n 个点能构成多少棵不同的二叉树。

答案也是一个原封不动的卡特兰数,虽然不能转化成进出栈问题,但是思路和进出栈问题差不多。

我们考虑枚举根节点的左子树和右子树的大小,假如左子树的大小为 i i i,那么右子树的大小就是 n − i − 1 n-i-1 ni1,那么枚举一下就是 a n s ( n ) = ∑ i = 0 n − 1 a n s ( i ) a n s ( n − i − 1 ) ans(n)=\sum_{i=0}^{n-1} ans(i)ans(n-i-1) ans(n)=i=0n1ans(i)ans(ni1)

3 3 3

接下来拿一道真题来讲吧!

[AHOI2012]树屋阶梯

题目大意: n n n 个矩形搭一个 n n n 格高的阶梯的方案数。

发现这题有一个性质,位于左下角的那个矩形的高加宽等于 n + 1 n+1 n+1

那么设它的高为 x x x,宽为 y y y,那么有 y = n + 1 − x y=n+1-x y=n+1x

我们发现,左下角的矩形构成了第 x x x 级的阶梯,假如将他去掉,那么问题转变成了两个子问题:在他的左边用 x − 1 x-1 x1 个矩形造一个 x − 1 x-1 x1 格高的阶梯;在他的上面用 y − 1 y-1 y1 个矩形造一个 y − 1 y-1 y1 格高的阶梯。

写出来就是 a n s ( n ) = ∑ i = 1 n a n s ( i − 1 ) a n s ( n + 1 − x − 1 ) ans(n)=\sum_{i=1}^n ans(i-1)ans(n+1-x-1) ans(n)=i=1nans(i1)ans(n+1x1),转化一下就是个裸的卡特兰数了。

代码详见这里。

练习

[HNOI2009]有趣的数列   题解
[TJOI2015]概率论     题解

你可能感兴趣的:(数论)