1.定义:卡特兰数:规定h(0)=1,而h(1)=1,h(2)=2,h(3)=5,h(4)=14,h(5)=42,h(6)=132,h(7)=429,h(8)=1430,h(9)=4862,h(10)=16796,h(11)=58786,h(12)=208012····················
通项公式为:
2.应用:①括号匹配问题(也就是比如2n=6,三对括号有多少种放置方式,求出所有满足要求个数),我用递归写了个代码,如下:
#include <iostream>
#include <vector>
#include <string>
#define MAX 6
using namespace std;
char res[MAX];
void print()
{
for (int i = 0; i < MAX; i++)
cout << res[i] << " ";
cout << endl;
}
void search(int idxLEFT, int idxRIGHT)//初代递归,时间复杂度比较大
{
if (idxLEFT > MAX / 2 || idxRIGHT>MAX/2 || idxRIGHT>idxLEFT)
return;
if (idxLEFT + idxRIGHT == MAX)
{print();
return;
}
res[idxLEFT + idxRIGHT] = '(';
search(idxLEFT + 1, idxRIGHT);
res[idxLEFT + idxRIGHT] = ')';
search(idxLEFT, idxRIGHT + 1);
}
int main() {
res[0] = '(';
search(1,0);
return 0;
}
或者代码里MAX可以改为四对,五对等括号匹配,都可以。运行结果:
②出栈次序问题。一个栈(无穷大)的进栈序列为1、2、3、...、n,有多少个不同的出栈序列?
类似:有2n个人排成一行进入剧场。入场费5元。其中只有n个人有一张5元钞票,另外n人只有10元钞票,剧院无其它钞票,问有多少中方法使得只要有10元的人买票,售票处就有5元的钞票找零?(将持5元者到达视作将5元入栈,持10元者到达视作使栈中某5元出栈);在图书馆一共6个人在排队,3个还《面试宝典》一书,3个在借《面试宝典》一书,图书馆此时没有了面试宝典了,求他们排队的总数?
③一个面试题:
12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少
种?
问题分析:
我们先把这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的出现前边必须有一个相应的0对应,所以从左到右的所有序列中0的个数要一直大于1的个数。
3.总结:什么时候想到用卡特兰数,本质就是说:
比如:从左到右的所有序列中0(左括号)的个数要一直大于1(右括号)的个数。
推广:从左到右的所有序列中“某个约束” 的个数要一直大于非约束 的个数。
参考:http://buptdtt.blog.51cto.com/2369962/832586/
http://www.cnblogs.com/yaoyueduzhen/p/5456490.html