一、卡特兰数
 
卡特兰数又称卡塔兰数,英文名Catalan number,是 组合数学 中一个常出现在各种计数问题中出现的 数列 。由以 比利时 的数学家欧仁·查理·卡塔兰 (1814–1894)命名。在这里表示对数学家的尊敬,同时。。。也因为他发明了这些难懂的东西,脑袋都被这些数学家弄炸了。
 
首先是卡特兰数的定义:令h(0)=1,h(1)=1,catalan数满足递推式:
 
 
h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n>=2)。 
可以根据上面的递推公式,写出递归的计算方案。
 
#include <stdio.h>
 
#include <assert.h>
 
int catalan(int n)
 
{
 
 assert(n>=0);
 
 if(0==n || 1==n)return 1;
 
 int num=0;
 
 for(int i=0;i<n;i++)
 
 {
 
  //在这里递归
 
  num+=catalan(i)*catalan(n-i-1);
 
 }
 
 return num;
 
}
 
 
 
int main()
 
{
 
 //输出正确结果
 
 printf("%d\n",catalan(8));
 
 return 0;
 
} 
这里我们可以采用循环的形式来优化。这里我就不再细提,接着往下看。
 
二、卡特兰数的另一个递归解
 
h(n)=c(2n,n)-c(2n,n+1)(n=1,2,3,...) 
其中c为组合数。
 
三、栈出栈顺序
 
题目:一个含有N个不同元素的待入栈序列,问存在多少种不同的出栈顺序。
 
解:这道题采用穷举显然不合适,可能会出现的方案有很多。我们在这里注意一下采用卡特兰数的思想。
 
我们将所有的出栈顺序按照出栈首个元素来分类:
 
a1(剩余序列),a2(剩余序列)......ai(剩余序列).......an(剩余序列)。
 
这样我们就可以采用递归的方法了。
 
我们就其中任意一种情况来分析,ai(剩余序列),如果ai是第一个出栈的,那么可以将整个序列分成两部分,一部分是a1~ai-1,一部分是ai+1~an。
 
前面一部分的出栈种类是C(i-1)。后面一部分序列是C(n-i),那么总共的序列是C(i-1)*C(n-i)。
 
那么考虑所有的n中情况。我们可以知道:
 
C(n)=C(0)*C(n-1)+C(1)*C(n-2) + ... + C(n-1)C(0)
 
也就是刚好是卡特兰数。
 
 
四、类似问题
 
类似于这样的问题还有矩阵链乘问题、凸多边三角形的划分、给定节点组成的二叉树。其本质都是递推的应用。










