Catalan数(卡塔兰数)

    卡塔兰数是组合数学中一个常在各种计数问题中出现的数列。数列的定义为C(0)=1,C(n)= C(0)*C(n-1) + C(1)*C(n-2) + … + C(n-1)C(0) ,其一般项公式为C(n) = C(2n,n)/(n + 1) 

    组合数学中有非常多的组合结构可以用卡塔兰数来计数。这里的例子分为两类:

    第1类:抽象模型为入栈出栈序列问题

   1.基本模型:一个栈(无穷大)的进栈序列为1,2,3,…,n,有多少个不同的出栈序列?

   [解析]n个元素的入栈出栈序列长度为2n。序列中的第1项必定是表示元素1入栈的,而元素1的出栈操作一定在序列中的第2i(表示偶数)个项,因为如果是在第2i - 1(表示奇数)个项,那么这中间包含了奇数个项,而这奇数个项肯定无法构成入栈出栈序列。

    设问题的解为f(n), 那么f(n) = f(0)*f(n-1) + f(1)*f(n-2) + … +f(n-1)*f(0)。其中f(0) * f(n-1)表示元素1进栈后立即出栈,此时序列中元素1的进栈与出栈操作间隔数为2 * 0,剩余2n-2个项,对应于n - 1个元素的入栈出栈序列。f(1)*f(n-2)表示元素1进栈与出栈操作间隔数为2 * 1,相当于1 2 2 1,剩余2n-4个项,对应于n - 2个元素的入栈出栈序列以此类推

    f(n) = f(0)*f(n-1) + f(1)*f(n-2) + … +f(n-1)*f(0) ,即Catalan数。C(n) = C(2n,n)/(n + 1) 

    该模型可用于证明Catalan数数列的通项公式 C(n) = C(2n,n)/(n + 1) ,证明过程如下:(参见《计算机程序设计艺术》第1卷:基本算法 第3版P508 习题4)

    由该模型可知,Catalan数的通项C(n), 等于含有n个S(表示入栈操作)和n个X(表示出栈操作)的合法的入栈出栈序列的个数。显然有C(2n,n)个含S和X各n个的序列。先计算这C(2n,n)个序列中不合法的序列数。在任何不合法的序列中,定出使得X的个数超过S的个数的第一个X的位置。然后,在从起始位置直到这个X的子序列中,互换S和X,结果是一个有(n + 1)个S和(n - 1)个X的序列。反过来,对于每一个有(n + 1)个S和(n - 1)个X的序列,我们都能通过逆过程得到相应的不合法序列。例如,由不合法序列XXSXSSS XXSSS转换得到SSXSXXX XXSSS,再通过逆过程即可得到原来的不合法序列。这种一一对应的关系说明了不合法序列的总数是C(2n,n-1) ,于是合法的入栈出栈序列的总数是C(2n,n)- C(2n,n-1) = C(2n,n)/(n + 1) 

    利用同样的思路,我们可以解决概率论中更一般的“抽签问题”,它实际上是要枚举所有的具有指定个数的S和X的合法序列,其中所谓"合法"是指从序列的起始处开始,直至序列中的任何位置所得的子序列中,X的个数都不能比S的个数多n(例如上例中n=1)。设序列中X的个数为k,S的个数为m,不合法的序列数为f(k,m,n)。如果k < m + n,则显然有f(k,m,n) = C(k+m,m)。如果k >= m + n,则在任何不合法的序列中,定出使得X的个数比S的个数多n的第一个X的位置。然后,在从起始位置直到这个X的子序列中,互换S和X,结果是一个有(m + n)个S和(k - n)个X的序列。反过来,对于每一个有(m + n)个S和(k - n)个X的序列,我们都能通过逆过程得到相应的不合法序列。例如,由不合法序列XXSXSSS XXSSS转换得到SSXSXXX XXSSS,再通过逆过程即可得到原来的不合法序列。这种一一对应的关系说明了不合法序列的总数f(k,m,n) = C(k+m,k - n)。综合这两种情况,可知不合法序列的总数f(k,m,n) = C(k+m,Min(m,k - n)),所以合法序列的总数是C(k+m,m)- C(k+m,Min(m,k - n))

   该模型可用于解决很多问题:

    2.有16个人排成一行进入剧场。入场费5元。其中8个A种人只有一张5元钞票,另外8个B种人只有一张10元钞票,售票处无其它钞票,每种人的购票次序都已固定,问有多少种售票序列使得只要有10元的人买票,售票处就有5元的钞票找零?

   [解析]将持5元者到达视作入栈操作,持10元者到达视作出栈操作,于是问题抽象成为8个元素的出栈序列问题,结果为C(8)

   [变形]

    若干人排成一行进入剧场。入场费5元。其中m个A种人只有一张5元钞票,另外k个B种人只有一张10元钞票,售票处无其它钞票,每种人的购票次序都已固定,问有多少种售票序列使得只要有10元的人买票,售票处就有5元的钞票找零?

   [解析]参见上面"抽签问题"的分析过程,不难得出结果为C(k+m,m)- C(k+m,Min(m,k - 1))

    3.一位大城市的律师在她住所以北4个街区和以东4个街区处工作,每天她走8个街区去上班。如果她从不穿越(但可以碰到)从家到办公室的对角线,那么有多少条可能的道路?

    [解析]将向东移动一个街区视作入栈,将向北移动一个街区视作出栈,于是问题抽象成为4个元素的出栈序列问题,结果为C(4)

    4.有12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问有多少种不同的排列方式?
    [解析]先把这12个人从矮到高排列,然后依次补入队列,用0表示对应的人排到第一排,用1表示对应的人排到第二排,那么每种方案必定对应着一个含有6个0,6个1的序列,且序列中每个1之前的0的个数必定大于1的个数。
    比如第一排:0 1 2 3 4 5,第二排:6 7 8 9 10 11就对应着序列             000000111111。 第一排:0 2 4 6 8 10, 第二排:1 3 5 7 9 11就对应着序列010101010101。
   将0看成入栈操作,1看成出栈操作,于是问题抽象成为6个元素的出栈序列问题,结果为C(6)

   第2类:抽象模型为Catalan数数列的定义式

   1.给定n个节点,能构成多少种形状不同的二叉树?
   [解析]设n个节点可构成C(n)种形状不同的二叉树,则C(0)=1。先取一个节点作为二叉树的根,然后左子树的节点数可依次设为0至n-1,相应的右子树的节点数则依次为n-1至0,两两配对相乘,得C(n)= C(0)*C(n-1) + C(1)*C(n-2) + … + C(n-1)C(0),即Catalan数

    2.对于矩阵连乘: P=A1×A2×A3×……×An,依据乘法结合律,不改变其顺序,只用括号表示成对的乘积,试问有几种括号化的方案?
   [解析]可以这样考虑,首先通过括号化,将P分成两个部分,然后分别对这两个部分进行括号化。比如分成(a1)×(a2×a3.....×an),然后再对(a1)和(a2×a3.....×an)分别括号化;又如分成(a1×a2)×(a3.....×an),然后再对(a1×a2)和(a3.....×an)括号化。

   设对于n个矩阵的括号化方案的种数为f(n),那么问题的解为

    f(n) = f(1)*f(n-1) + f(2)*f(n-2) + f(3)*f(n-3) + f(n-1)*f(1)。其中f(1)*f(n-1)表示分成(a1)×(a2×a3.....×an)两部分,然后分别括号化。

    f(n) = f(1)*f(n-1) + f(2)*f(n-2) + f(3)*f(n-3) + f(n-1)*f(1) = 

    C(n-1) = C(0)*C(n-2) + C(1)*C(n-3) + … + C(n-2)C(0)

    3.将一个有n个顶点的凸多边形划分成三角形有多少种方法?

   [解析] 以凸多边形的一边为基,设这条边的2个顶点分别为A和B。从剩余顶点中任选1个,可以将凸多边形分成三个部分,中间是一个三角形,左右两边分别是两个凸多边形,然后分别求解左右两个凸多边形。

   设问题的解f(n),那么f(n) = f(2)*f(n-1) + f(3)*f(n-2) + ......f(n-2)*f(3) + f(n-1)*f(2)。f(2)*f(n-1)表示当三个相邻的顶点构成一个三角形时,另外两个部分的顶点数分别为2和n-1。

    f(n) = f(2)*f(n-1) + f(3)*f(n-2) + ......f(n-2)*f(3) + f(n-1)*f(2) = C(n-2) = C(0)*C(n-3) + C(1)*C(n-4) + … + C(n-3)C(0)

   4.n对括号有多少种匹配方式?

   [解析]:分析这个问题的思路与出栈序列问题是相似的。

    n对括号的符号序列长度为2n。序列中的第1项必定是左括号,而与该左括号匹配的右括号一定在序列中的第2i(表示偶数)个项,因为如果是在第2i - 1(表示奇数)个项,那么这中间包含了奇数个项,而这奇数个项肯定无法构成括号对。

    设问题的解为f(n), 那么f(n) = f(0)*f(n-1) + f(1)*f(n-2) + … +f(n-1)*f(0)。其中f(0) * f(n-1)表示1对括号的左括号与右括号紧邻,此时序列中第1对括号间隔数为2 * 0,剩余2n-2个项,对应于n - 1对括号的符号序列。f(1)*f(n-2)表示1对括号的左括号与右括号间隔数为2 * 1,相当于(()),剩余2n-4个项,对应于n - 2对括号的符号序列以此类推

   f(n) = f(0)*f(n-1) + f(1)*f(n-2) + … +f(n-1)*f(0),即Catalan数。

   [变形]

    对于集合{1,2,… 2n},其不交叉划分有多少个?

    这里解释一下不交叉划分,对于集合{a,b}和{c,d},如果它们组成了两个区间[a,b]和[c,d],那么以下四种情况就是不交叉的:a<c<d<b,a<b<c<d,c<a<b<d与c<d<a<b,也就是说两个区间可以包含或者相离,此时我们称集合{a,b}和{c,d}是不交叉的。对于集合{1,2,… 2n},将里面的元素每两个划分成一个子集,共有n个子集,若任意两个子集都是不交叉的,那么我们称此时的划分为不交叉划分。例如集合{1,2,3,4,5,6}的不交叉划分有五个:{{1,2},{3,4},{5,6}},{{1,2},{3,6},{4,5}},{{1,4},{2,3},{5,6}},{{1,6},{2,3},{4,5}}和{{1,6},{2,5},{3,4}}。

    设问题的解为f(n),对于集合的每个子集,将其较小的数用左括号代替,较大的数用右括号代替,于是原问题就等价于n对括号有多少种匹配方式了,所以f(n) = C(n)。

    5.在圆上选择2n个点,用n条线段将这些点成对连接起来,求使所得的n条线段不相交的连接方法数。

    [解析]:分析这个问题的思路与出栈序列问题是相似的。

    以其中一个点为基点,编号为1,然后按顺时针方向将其它(2n - 1)个点依次编号。与顶点1相连的顶点的编号一定是偶数,否则,在连接这两个顶点的线段的左右两侧各含有奇数个顶点,势必会各有1个点被孤立,即在一条线段的两侧分别有一个孤立点,从而导致必然有两条线段相交。设选中的基点为A,与它连接的点为B,那么线段AB将所有顶点分成两个部分,一部分位于线段AB的左侧,另一部分位于线段AB的右侧。然后分别对这两部分求解即可。          

    设问题的解为f(n), 那么f(n) = f(0)*f(n-1) + f(1)*f(n-2) + … +f(n-1)*f(0)。其中f(0) * f(n-1)表示顶点1与顶点2相连,此时位于该线段左侧的顶点的个数为0,而位于该线段右侧的顶点的个数为2n-2。f(1)*f(n-2)顶点1与顶点4相连,此时位于该线段左侧的顶点的个数为2,而位于该线段右侧的顶点的个数为2n-4。以此类推。

    f(n) = f(0)*f(n-1) + f(1)*f(n-2) + … +f(n-1)*f(0) ,即Catalan数。

    6.将一个n层的阶梯切割成n个矩形,如下图所示(取n = 4示例),有多少种切法?

    [解析]

   n=4时的阶梯如下图所示:

   *  +  +  #

   +  +  #

   +  #

   #

   我们注意到每个切割出来的矩形都必须包括一块标示为 #的小正方形,于是我们枚举每个 #与*标示的对角作为矩形,剩下的两个小阶梯就是两个更小的子问题了,设问题的解为f(n),于是f(n) = f(0)*f(n-1) + f(1)*f(n-2) + … +f(n-1)*f(0) ,即Catalan数。

转载于:https://www.cnblogs.com/laifeiyao/archive/2013/05/08/3066043.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值