Calatan Number

calatan数的定义

  卡特兰数的定义为:

    由n个"+1"和n个"-1"构成的2n项:(a_{1}、a_{2}、a_{3}、...、a_{2n})其部分和满足:(a_{1}+a_{2} + a_{3}+...+a_{k}geqslant0 qquad k = 1,2,...,2n)的数列为第n个卡特兰数。

Calatan数的公式

卡特兰数的递推公式:[1]
令$ h(0) = 1,h(1) = 1 (则calatan数满足递归式:</br> &#8195; &#8195; &#8195;) h(n) = h(0)h(n-1) + h(1)h(n-2) + ...+ h(n-1)h(0) ;n >= 2$

另类递推公式:

     $h(n) = h(n-1)(4n-2)/(n+1) $

该递推关系的解为:

     (C_n = {1 above{1pt} n+1}dbinom{2n}{n})

卡特兰数:

        $C_0 = 1 $

        $C_1 = 1 $

        $C_2 = 2 $

        $C_3 = 5 $

        $C_4 = 14 $

        $C_5 = 42 $

calatan的应用

1.括号匹配问题

  由n个左括号和n个右括号组成的有效表达式的个数,是第n个卡特兰数。

正如 (C_3 = 5),即如下所示:

2. 进出栈问题

  一个足够大的栈的进栈序列为 $ 1,2,3,...n $ ,则其有多少个不同的出栈顺序?

  我们可以这样想,假设k是最后一个出栈的数,比k早进栈且早出栈的数有k-1个,一共有h(k-1)种方案;比k玩进栈且早出栈的数有n-k个,一共有h(n-k)种方案。所以一共的出栈方案有$ h(k-1)*h(n-k) $种方案。显而易见,k取不同值时,产生的出栈序列是相互独立的,因为k的值为从1到n,所以出栈方案为:

    $ h(n) = h(0)*h(n-1) + h(1)*h(n-2) + ...+ h(n-1)h(0) $

2. 电影购票问题

电影票每张50元,如果有m+n个人排队买票,其中m个人各持有50元面值的钞票张,另外n个人各持有100元面值的钞票张,而票房没有预备找零.有多少种方法可以将这个人排成一列,顺序购票,使得无需因为等待找零而耽误时间.

   
image

  如上图所示,在nxn的方格中,从一个角到另一个角(成对角线),不能跨越对角线的路径数。

  只要将向右记为+1,向上记为-1,问题就转化为了进出栈问题。
具体参考文献 [2]

代码实现

#include <iostream> 
using namespace std;

// A recursive function to find nth catalan number 
unsigned long int catalan(unsigned int n)
{
	// Base case 
	if (n <= 1)
		return 1;

	// catalan(n) is sum of catalan(i)*catalan(n-i-1) 
	unsigned long int res = 0;
	for (int i = 0; i < n; i++)
		res += catalan(i) * catalan(n - i - 1); //h(n) = h(0)*h(n-1) + h(1)*h(n-2)+h(2)*h(n-3)+...+h(n)

	return res;
}

// Driver program to test above function 
int main()
{
	for (int i = 0; i < 10; i++)
		cout << catalan(i) << " ";
	return 0;
}


  1. 参考文献一:https://brilliant.org/wiki/catalan-numbers/ ↩︎

  2. 参考文献二:http://lanqi.org/interests/10939/ ↩︎

原文地址:https://www.cnblogs.com/ccpang/p/12106173.html