Catalan数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Catalan数相关的知识,希望对你有一定的参考价值。

我要Catalan数h(n)与h(n-1)之间的递推关系式,高手快来帮忙.
鄙视楼下两个,自己推公式,那个我不要,我要Catalan数h(n)与h(n-1)之间的

参考技术A 通项都告你了:
h(n)=c(2n,n)/(n+1)
Catalan数h(n)与h(n-1)之间的关系你写不出来???
h(n)= h(0)*h(n-1) + h(1)*h(n-2) + ... + h(n-1)h(0) 是用生成函数解决的……

生成函数(也有叫做“母函数”的,但是我觉得母函数不太好听)是说,构造这么一个多项式函数g(x),使得x的n次方系数为f(n)。
生成函数最绝妙的是,某些生成函数可以化简为一个很简单的函数。也就是说,不一定每个生成函数都是用一长串多项式来表示的。比如,这个函数f(n)=1 (n当然是属于自然数的),它的生成函数就应该是g(x)=1+x+x^2+x^3+x^4+...(每一项都是一,即使n=0时也有x^0系数为1,所以有常数项)。再仔细一看,这就是一个有无穷多项的等比数列求和嘛。如果-1<x<1,那么g(x)就等于1/(1-x)了。在研究生成函数时,我们都假设级数收敛,因为生成函数的x没有实际意义,我们可以任意取值。于是,我们就说,f(n)=1的生成函数是g(x)=1/(1-x)。

我们举一个例子说明,一些具有实际意义的组合问题也可以用像这样简单的一个函数全部表示出来。
考虑这个问题:从二班选n个MM出来有多少种选法。学过简单的排列与组合的同学都知道,答案就是C(4,n)。也就是说。从n=0开始,问题的答案分别是1,4,6,4,1,0,0,0,...(从4个MM中选出4个以上的人来方案数当然为0喽)。那么它的生成函数g(x)就应该是g(x)=1+4x+6x^2+4x^3+x^4。这不就是……二项式展开吗?于是,g(x)=(1+x)^4。
你或许应该知道,(1+x)^k=C(k,0)x^0+C(k,1)x^1+...+C(k,k)x^k;但你或许不知道,即使k为负数和小数的时候,也有类似的结论:(1+x)^k=C(k,0)x^0+C(k,1)x^1+...+C(k,k)x^k+C(k,k+1)x^(k+1)+C(k,k+2)x^(k+2)+...(一直加到无穷;式子看着很别扭,自己写到草稿纸上吧,毕竟这里输入数学式子很麻烦)。其中,广义的组合数C(k,i)就等于k(k-1)(k-2)(k-i+1)/i!,比如C(4,6)=4*3*2*1*0*(-1)/6!=0,再比如C(-1.4,2)=(-1.4)*(-2.4)/2!=1.68。后面这个就叫做牛顿二项式定理。当k为整数时,所有i>k时的C(k,i)中分子都要“越过”0这一项,因此后面C(k,k+1),C(k,k+2)之类的都为0了,与我们的经典二项式定理结论相同;不同的是,牛顿二项式定理中的指数k可以是任意实数。

我们再举一个例子说明一些更复杂的生成函数。n=x1+x2+x3+...+xk有多少个非负整数解?这道题是学排列与组合的经典例题了。把每组解的每个数都加1,就变成n+k=x1+x2+x3+...+xk的正整数解的个数了。教材上或许会出现这么一个难听的名字叫“隔板法”:把n+k个东西排成一排,在n+k-1个空格中插入k-1个“隔板”。答案我们总是知道的,就是C(n+k-1,k-1)。它就等于C(n+k-1,n)。它关于n的生成函数是g(x)=1/(1-x)^k。这个生成函数是怎么来的呢?其实,它就是(1-x)的-k次方。把(1-x)^(-k)按照刚才的牛顿二项式展开,我们就得到了x^n的系数恰好是C(n+k-1,n),因为C(-k,n)*(-x)^n=[(-1)^n*C(n+k-1,n)]*[(-1)^n*x^n]=C(n+k-1,n)x^n。这里看晕了不要紧,后文有另一种方法可以推导出一模一样的公式。事实上,我们有一个纯组合数学的更简单的解释方法。因为我们刚才的几何级数1+x+x^2+x^3+x^4+...=1/(1-x),那么(1+x+x^2+x^3+x^4+...)^k就等于1/(1-x)^k。仔细想想k个(1+x+x^2+x^3+x^4+...)相乘是什么意思。(1+x+x^2+x^3+x^4+...)^k的展开式中,n次项的系数就是我们的答案,因为它的这个系数是由原式完全展开后k个指数加起来恰好等于n的项合并起来得到的。

现在我们引用《组合数学》上暴经典的一个例题。很多书上都会有这类题。
我们要从苹果、香蕉、橘子和梨中拿一些水果出来,要求苹果只能拿偶数个,香蕉的个数要是5的倍数,橘子最多拿4个,梨要么不拿,要么只能拿一个。问按这样的要求拿n个水果的方案数。
结合刚才的k个(1+x+x^2+x^3+x^4+...)相乘,我们也可以算出这个问题的生成函数。

引用内容
g(x)=(1+x^2+x^4+...)(1+x^5+x^10+..)(1+x+x^2+x^3+x^4)(1+x)
=[1/(1-x^2)]*[1/(1-x^5)]*[(1-x^5)/(1-x)]*(1+x) (前两个分别是公比为2和5的几何级数,
第三个嘛,(1+x+x^2+x^3+x^4)*(1-x)不就是1-x^5了吗)
=1/(1-x)^2 (约分,把一大半都约掉了)
=(1-x)^(-2)=C(1,0)+C(2,1)x+C(3,2)x^2+C(4,3)x^3... (参见刚才对1/(1-x)^k的展开)
=1+2x+3x^2+4x^3+5x^4+....

于是,拿n个水果有n+1种方法。我们利用生成函数,完全使用代数手段得到了答案!
如果你对1/(1-x)^k的展开还不熟悉,我们这里再介绍一个更加简单和精妙的手段来解释1/(1-x)^2=1+2x+3x^2+4x^3+5x^4+....。
1/(1-x)=1+x+x^2+x^3+x^4+...是前面说过的。我们对这个式子等号两边同时求导数。于是,1/(1-x)^2=1+2x+3x^2+4x^3+5x^4+....。一步就得到了我们所需要的东西!不断地再求导数,我们同样可以得到刚才用复杂的牛顿二项式定理得到的那个结论(自己试试吧)。生成函数还有很多其它的处理手段,比如等式两边同时乘以、除以常数(相当于等式右边每一项乘以、除以常数),等式两边同时乘以、除以一个x(相当于等式右边的系数“移一位”),以及求微分积分等。神奇的生成函数啊。
我们用两种方法得到了这样一个公式:1/(1-x)^n=1+C(n,1)x^1+C(n+1,2)x^2+C(n+2,3)x^3+...+C(n+k-1,k)x^k+...。这个公式非常有用,是把一个生成函数还原为数列的武器。而且还是核武器。

接下来我们要演示如何使用生成函数求出Fibonacci数列的通项公式。
Fibonacci数列是这样一个递推数列:f(n)=f(n-1)+f(n-2)。现在我们需要求出它的生成函数g(x)。g(x)应该是一个这样的函数:
g(x)=x+x^2+2x^3+3x^4+5x^5+8x^6+13x^7+...
等式两边同时乘以x,我们得到:
x*g(x)=x^2+x^3+2x^4+3x^5+5x^6+8x^7+...
就像我们前面说过的一样,这相当于等式右边的所有系数向右移动了一位。
现在我们把前面的式子和后面的式子相加,我们得到:
g(x)+x*g(x)=x+2x^2+3x^3+5x^4+8x^5+...
把这最后一个式子和第一个式子好好对比一下。如果第一个式子的系数往左边移动一位,然后把多余的“1”去掉,就变成了最后一个式子了。由于递推函数的性质,我们神奇地得到了:g(x)+x*g(x)=g(x)/x-1。也就是说,g(x)*x^2+g(x)*x-g(x)=-x。把左边的g(x)提出来,我们有:g(x)(x^2+x-1)=-x。于是,我们得到了g(x)=x/(1-x-x^2)。
现在的任务是要把x/(1-x-x^2)还原成通项公式。这不是我们刚才的1/(1-x)^n的形式,我们要把它变成这种形式。我们发现,1-x-x^2=[1-(1-√5)x/2]*[1-(1+√5)x/2] ((1-√5)/2和(1+√5)/2是怎么算出来的?显然它们应该是x^2-x-1=0的两个根)。那么x/(1-x-x^2)一定能表示成?/[1-(1-√5)x/2]+?/[1-(1+√5)x/2]的形式(再次抱歉,输入数学公式很麻烦,将就看吧)。这是一定可以的,因为适当的?的取值可以让两个分式通分以后分子加起来恰好为一个x。?取值应该是多少呢?假设前面一个?是c1,后面那个是c2,那么通分以后分子为c1*[1-(1+√5)x/2]+c2*[1-(1-√5)x/2],它恰好等于x。我们得到这样两个式子:常数项c1+c2=0,以及一次项-c1*(1+√5)/2-c2*(1-√5)/2=1。这两个式子足够我们解出c1和c2的准确值。你就不用解了,我用的Mathematica 5.0。解出来c1=-1/√5,c2=1/√5。你不信的话你去解吧。现在,我们把x/(1-x-x^2)变成了-(1/√5)/[1-(1-√5)x/2] + (1/√5)/[1-(1+√5)x/2]。我们已经知道了1/[1-(1-√5)x/2]的背后是以(1-√5)/2为公比的等比数列,1/[1-(1+√5)x/2]所表示的数列公比为(1+√5)/2。那么,各乘以一个常数,再相加,我们就得到了Fibonacci数列的通项公式:f(n)=-(1/√5)*[(1-√5)/2]^n + (1/√5)*[(1+√5)/2]^n。或许你会问,这么复杂的式子啊,还有根号,Fibonacci数列不都是整数吗?神奇的是,这个充满根号的式子对于任何一个自然数n得到的都是整数。熟悉用特征方程解线性递推方程的同学应该知道,以上过程实质上和找特征根求解没有区别。事实上,用上面所说的方法,我们可以求出任何一个线性齐次递推方程的通项公式。什么叫做线性齐次递推呢?就是这样的递推方程:f(n)等于多少个f(n-1)加上多少个f(n-2)加上多少个f(n-3)等等。Fibonacci数列的递推关系就是线性齐次递推关系。

我们最后看一个例子。我们介绍硬币兑换问题:我有1分、2分和5分面值的硬币。请问凑出n分钱有多少种方法。想一下刚才的水果,我们不难得到这个问题的生成函数:g(x)=(1+x+x^2+x^3+...)(1+x^2+x^4+...)(1+x^5+x^10+..)=1/[(1-x)(1-x^2)(1-x^5)]。现在,我们需要把它变成通项公式。我们的步骤同刚才的步骤完全相同。我们把(1-x)(1-x^2)(1-x^5)展开,得到1-x-x^2+x^3-x^5+x^6+x^7-x^8。我们求出-1+x+x^2-x^3+x^5-x^6-x^7+x^8=0的解,得到了以下8个解:-1,1,1,1,-(-1)^(1/5),(-1)^(2/5),-(-1)^(3/5),(-1)^(4/5)。这个不是我解出来的,我还是用的Mathematica 5.0。不是我不想解,而是我根本不会解这个8次方程。这也是为什么信息学会涉及这些东西的原因:次数稍微一高,只好交给计算机解决了。于是,(1-x)(1-x^2)(1-x^5)=(1+x)(1-x)^3(1+(-1)^(1/5) x)()()() (省略不写了)。注意那个(1-x)^3。由于等根的出现,我们不得不把(1-x)^3所包含的(1-x)和(1-x)^2因子写进一会儿的分母里,不然会导致解不出合适的c来。你可以看到很多虚数。不过没关系,这些虚数同样参与运算,就像刚才的根式一样不会影响到最后结果的有理性。然后,我们像刚才一样求出常数满足1/(1-x)(1-x^2)(1-x^5)=c1/()+c2/(1-x)+c3/(1-x)^2+c4/(1-x)^3...+c8/()。这个解太复杂了,我用Mathematica解了几分钟,打印出了起码几十KB的式子。虽然复杂,但我确实是得到了通项公式。你有兴趣的话可以尝试用Mathematica解决一下1/[(1-x)(1-x^3)] (只有1分和3分的硬币)。解c的值时可以用SolveAlways[]函数。你可以亲眼见到,一个四五行的充满虚数的式子最后总是得到正确的整数答案。

生成函数还有很多东西,推导Catalan数列啊,指数生成函数啊,之类的。我有空再说吧,已经5000多个字了。

huyichen一直在问那道题。很显然,那道题目和上面的兑换硬币有些联系。事实上,很多与它类似的题目都和生成函数有关。但那个题却没有什么可以利用生成函数的地方(或许我没想到吧)。或许每个max的值有什么方法用生成函数解出来,但整个题目是不大可能用生成函数解决的。
近来有个帖子问一道“DP天牛”题目的。那个题目也是这样,很多与它类似的题目都和DP有关,但那道题却不大可能动规。我总觉得它可以归约到装箱问题(考虑体积关系,最少要几个箱子才能把物品放完),而后者貌似属于NPC。或许我错了吧,现在没事就在研究理论的东西,很久没有想过OI题了,这方面的能力已经开始退化了。本回答被提问者采纳
参考技术B 中文:卡特兰数
原理:
令h(1)=1,catalan数满足递归式:
h(n)= h(0)*h(n-1) + h(1)*h(n-2) + ... + h(n-1)h(0) (其中n>=2)
该递推关系的解为:
h(n)=c(2n,n)/(n+1) (n=1,2,3,...)

我并不关心其解是怎么求出来的,我只想知道怎么用catalan数分析问题。
我总结了一下,最典型的三类应用:(实质上却都一样,无非是递归等式的应用,就看你能不能分解问题写出递归式了)
1.括号化问题。
矩阵链乘: P=a1×a2×a3×……×an,依据乘法结合律,不改变其顺序,只用括号表示成对的乘积,试问有几种括号化的方案?(h(n)种)

2.出栈次序问题。
一个栈(无穷大)的进栈序列为1,2,3,..n,有多少个不同的出栈序列?

类似:有2n个人排成一行进入剧场。入场费5元。其中只有n个人有一张5元钞票,另外n人只有10元钞票,剧院无其它钞票,问有多少中方法使得只要有10元的人买票,售票处就有5元的钞票找零?(将持5元者到达视作将5元入栈,持10元者到达视作使栈中某5元出栈)

3.将多边行划分为三角形问题。
将一个凸多边形区域分成三角形区域的方法数?

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

类似:在圆上选择2n个点,将这些点成对连接起来使得所得到的n条线段不相交的方法数?

(转载)Catalan数——卡特兰数

Catalan数——卡特兰数 
今天阿里淘宝笔试中碰到两道组合数学题,感觉非常亲切,但是笔试中失踪推导不出来
后来查了下,原来是Catalan数。悲剧啊,现在整理一下

一、Catalan数的定义令h(1)=1,Catalan数满足递归式:h(n) = h(1)*h(n-1) + h(2)*h(n-2) + ... + h(n-1)h(1),n>=2该递推关系的解为:h(n) = C(2n-2,n-1)/n,n=1,2,3,...(其中C(2n-2,n-1)表示2n-2个中取n-1个的组合数)

问题描述:
12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种?
这个笔试题,很YD,因为把某个递推关系隐藏得很深。

问题分析:
我们先把这12个人从低到高排列,然后,选择6个人排在第一排,那么剩下的6个肯定是在第二排.
用0表示对应的人在第一排,用1表示对应的人在第二排,那么含有6个0,6个1的序列,就对应一种方案.
比如000000111111就对应着
第一排:0 1 2 3 4 5
第二排:6 7 8 9 10 11
010101010101就对应着
第一排:0 2 4 6 8 10
第二排:1 3 5 7 9 11
问题转换为,这样的满足条件的01序列有多少个。
观察1的出现,我们考虑这一个出现能不能放在第二排,显然,在这个1之前出现的那些0,1对应的人
要么是在这个1左边,要么是在这个1前面。而肯定要有一个0的,在这个1前面,统计在这个1之前的0和1的个数。
也就是要求,0的个数大于1的个数。
OK,问题已经解决。
如果把0看成入栈操作,1看成出栈操作,就是说给定6个元素,合法的入栈出栈序列有多少个。
这就是catalan数,这里只是用于栈,等价地描述还有,二叉树的枚举、多边形分成三角形的个数、圆括弧插入公式中的方法数,其通项是c(2n, n)/(n+1)。

在<<计算机程序设计艺术>>,第三版,Donald E.Knuth著,苏运霖译,第一卷,508页,给出了证明:
问题大意是用S表示入栈,X表示出栈,那么合法的序列有多少个(S的个数为n)
显然有c(2n, n)个含S,X各n个的序列,剩下的是计算不允许的序列数(它包含正确个数的S和X,但是违背其它条件)。
在任何不允许的序列中,定出使得X的个数超过S的个数的第一个X的位置。然后在导致并包括这个X的部分序列中,以S代替所有的X并以X代表所有的S。结果是一个有(n+1)个S和(n-1)个X的序列。反过来,对一垢一种类型的每个序列,我们都能逆转这个过程,而且找出导致它的前一种类型的不允许序列。例如XXSXSSSXXSSS必然来自SSXSXXXXXSSS。这个对应说明,不允许的序列的个数是c(2n, n-1),因此an = c(2n, n) - c(2n, n-1)。

验证:其中F表示前排,B表示后排,在枚举出前排的人之后,对应的就是后排的人了,然后再验证是不是满足后面的比前面对应的人高的要求。

 

#include <iostream>
using namespace std;

int bit_cnt(int n)
{
    int result = 0;
    for (; n; n &= n-1, ++result);
    return result;
}

int main(void)
{
    int F[6], B[6];
    int i,j,k,state,ok,ans = 0;
    for (state = 0; state < (1 << 12); ++state)
    {
        if (bit_cnt(state) == 6)
        {
            i = j = 0;
            for (int k = 0; k < 12; ++k)
            {
                if(state&(1<<k))
                    F[i++] = k;
                else
                    B[j++] = k;
            }
            ok = 1;
            for (k = 0; k < 6; ++k)
            {
                if (B[k] < F[k])
                {
                    ok = 0;
                    break;
                }
            }
            ans += ok;
        }
    }
    cout << ans << endl;
    return 0;
}

 

结果:132

而c(12, 6)/7 = 12*11*10*9*8*7/(7*6*5*4*3*2) = 132

注意:c(2n, n)/(n+1) = c(2n, n) - c(2n, n-1)
估计出题的人也读过<<计算机程序艺术>>吧。

PS:
另一个很YD的问题:
有编号为1到n(n可以很大,不妨在这里假定可以达到10亿)的若干个格子,从左到右排列。
在某些格子中有一个棋子,不妨设第xi格有棋子(1<=i<=k, 1<=k<=n)
每次一个人可以把一个棋子往左移若干步,但是不能跨越其它棋子,也要保证每个格子至多只有一个棋子。
两个人轮流移动,移动不了的为输,问先手是不是有必胜策略。

三、Catalan数的典型应用:

1、括号化问题。矩阵链乘: P=A1×A2×A3×……×An,依据乘法结合律,不改变其顺序,只用括号表示成对的乘积,试问有几种括号化的方案?

   一个有n个X和n个Y组成的字串,且所有的部分字串皆满足X的个数大于等于Y的个数。以下为长度为6的dyck words:
                            XXXYYY     XYXXYY    XYXYXY    XXYYXY    XXYXYY
    将上例的X换成左括号,Y换成右括号,Cn表示所有包含n组括号的合法运算式的个数:
                         ((()))     ()(())      ()()()      (())()      (()())

2、将多边行划分为三角形问题。将一个凸多边形区域分成三角形区域(划分线不交叉)的方法数?

类似:在圆上选择2n个点,将这些点成对连接起来使得所得到的n条线段不相交的方法数?

技术分享

3、出栈次序问题。一个栈(无穷大)的进栈序列为1、2、3、...、n,有多少个不同的出栈序列?
类似:有2n个人排成一行进入剧场。入场费5元。其中只有n个人有一张5元钞票,另外n人只有10元钞票,剧院无其它钞票,问有多少中方法使得只要有10元的人买票,售票处就有5元的钞票找零?(将持5元者到达视作将5元入栈,持10元者到达视作使栈中某5元出栈)

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

技术分享

分析:对于每一个数来说,必须进栈一次、出栈一次。我们把进栈设为状态‘1’,出栈设为状态‘0’。n个数的所有状态对应n个1和n个0组成的2n位二进制数。由于等待入栈的操作数按照1‥n的顺序排列、入栈的操作数b大于等于出栈的操作数a(a≤b),因此输出序列的总数目=由左而右扫描由n个1和n个0组成的2n位二进制数,1的累计数不小于0的累计数的方案种数。

4、给顶节点组成二叉树的问题。
  给定N个节点,能构成多少种形状不同的二叉树?
  (一定是二叉树!先取一个点作为顶点,然后左边依次可以取0至N-1个相对应的,右边是N-1到0个,两两配对相乘,就是h(0)*h(n-1) + h(2)*h(n-2) + ...... + h(n-1)h(0)=h(n))   (能构成h(N)个)
技术分享

       在2n位二进制数中填入n个1的方案数为c(2n,n),不填1的其余n位自动填0。从中减去不符合要求(由左而右扫描,0的累计数大于1的累计数)的方案数即为所求。
       不符合要求的数的特征是由左而右扫描时,必然在某一奇数位2m+1位上首先出现m+1个0的累计数和m个1的累计数,此后的2(n-m)-1位上有n-m个 1和n-m-1个0。如若把后面这2(n-m)-1位上的0和1互换,使之成为n-m个0和n-m-1个1,结果得1个由n+1个0和n-1个1组成的2n位数,即一个不合要求的数对应于一个由n+1个0和n-1个1组成的排列。
       反过来,任何一个由n+1个0和n-1个1组成的2n位二进制数,由于0的个数多2个,2n为偶数,故必在某一个奇数位上出现0的累计数超过1的累计数。同样在后面部分0和1互换,使之成为由n个0和n个1组成的2n位数,即n+1个0和n-1个1组成的2n位数必对应一个不符合要求的数。

因而不合要求的2n位数与n+1个0,n-1个1组成的排列一一对应。

显然,不符合要求的方案数为c(2n,n+1)。由此得出输出序列的总数目=c(2n,n)-c(2n,n+1)=1/(n+1)*c(2n,n)。
(这个公式的下标是从h(0)=1开始的)



























































以上是关于Catalan数的主要内容,如果未能解决你的问题,请参考以下文章

Catalan数

Catalan数

catalan数

Catalan数

Catalan 数

Catalan数