卡特兰数

一、引入

        首先思考这样一个问题:给定n个不同的正整数1~n,依次进行出栈入栈操作,出栈的顺序有多少种?

        对于每个正整数都会入栈一次、出栈一次,我们将入栈记为+1,出栈记为-1,会得到如下的序列:

        +1,-1,+1,+1,....,+1,-1,记总和为total,因为每个元素只会分别入栈出栈各一次,所以total=0

        又因为栈中的元素个数不可能为负数,由此可以得到这个序列的所有前缀和均大于等于0

        我们记其中一个前缀串中,+1的个数为x,-1的个数为y,会得到x-y>=0(即任意一个前缀和大于等于0),即y<=x,其中1<=x<=n,1<=y<=n

        

        从图中看就是选出一条路径从(0,0)到达(n,n),只能向右或向上走,并且不能越过y=x这条直线的路径即为合法的出栈序列,那么出栈序列数即为这样的路径数记为Hn

        那么如何求呢?

        合法路径数=总路径数-非法路径数

        先求总路径数,在2n次移动中选n次向右移动,即\binom{2n}{n}

        再求非法路径数,即越过对角线的路径

        把y=x+1这条线画出来,碰到即说明是一条非法路径。

       

        所有的非法路径与这条线有至少一个交点,把第一个交点设为(a,a+1),把(a,a+1)之后的路径全部按照 y=x+1 这条线对称过去,这样,最后的终点就会变成(n-1,n+1)。

        所有非法路径对称后都唯一对应着一条到(n-1,n+1)的路径,所以非法路径数就是\binom{n-1}{2n},合法路径数就是\binom{2n}{n}-\binom{2n}{n-1},即Hn=\binom{2n}{n}-\binom{2n}{n-1}

        继续推导:

         

        继续推导不难得出如下的通项公式:

        Hn即为卡特兰数

二、算法例题:

Python代码如下:

n = int(input())
f = [0]*20
f[0] = 1
for i in range(1,n+1):
    f[i] = f[i-1]*(4*i-2)//(i+1)
print(f[n])

三、卡特兰数的应用

1、一个有n个0和n个1组成的字串,且所有的前缀字串皆满足1的个数不超过0的个数。这样的字串个数有多少?

        将0记为+1,1记为-1。

2、包含n组括号的合法运算式的个数有多少?

        对于左括号入栈记为+1,出栈记为-1

3、n个节点可构造多少个不同的二叉树?

        我们采用数组存储二叉树的节点:[1,0,1,0....]即可得到1、0交错的数组,由二叉树的性质可以得知:前缀串中0的个数不超过1的个数。到此我们又将这个问题转化成了问题1,将1记为+1,0记为-1

4、在圆上选择2n个点,将这些点成对连接起来使得所得到的n条弦不相等的方法数?

从左上第一个点开始按照顺时针进行连接,出点记为+1,入点记为-1,对于一个合法连接可以看到前缀和总是大于等于0,下面举一个反例

由于圆形的对称性,我们从第一个出点开始,即一个+1开始,图中的绿点开始到第三个点前缀和为-1,不合法

由此我们又将此问题转化为了问题1

5、通过连结顶点而将n+2边的凸多边形分成n个三角形的方法数?

通项公式推导过程:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值