【新年新气象_1】卡特兰(Catalan)数入门及应用

标题表示了一种在春节期间坚持更新BLOG的行为艺术。。

下边开始正式介绍:卡特兰数(Catalan Number)

定义(第N个卡特兰数用h(n)表示):令h(0)=1,h(1)=1,则catalan数满足关系式:

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

即h(2)=h(0)h(1)+h(1)h(0)=2

h(3)=h(0)h(2)+h(1)h(1)+h(2)h(0)=5

......


应用:

1、给定N个节点,能够组成多少种不同的二叉树?

2、一个无穷栈的进栈序列为1..2...n,有多少种不同的出栈序列

3、P=a1*a2*a3*a4*.......an,用括号表示成对的乘积,有多少种方案?

答案: h(n)

。。。


示例代码(HDU1023):点击打开链接

讨论火车的出栈次序,用卡特兰数模板套用即可。需要注意的是卡特兰数一般都很大。

#include <iostream>
#include <stdio.h>
#include <cmath>
using namespace std;

int a[105][105];    //大数卡特兰数,第二维为某位数 
int b[105];         //卡特兰数的长度

void catalan()  //求卡特兰数
{
    int i, j, len, carry, temp;
    a[1][0] = b[1] = 1;
    len = 1;
    for(i = 2; i <= 100; i++)
    {
        for(j = 0; j < len; j++)    //乘法
            a[i][j] = a[i-1][j]*(4*(i-1)+2);
        carry = 0;
        for(j = 0; j < len; j++)    //处理相乘结果
        {
            temp = a[i][j] + carry;
            a[i][j] = temp % 10;
            carry = temp / 10;
        }
        while(carry)    //进位处理
        {
            a[i][len++] = carry % 10;
            carry /= 10;
        }
        carry = 0;
        for(j = len-1; j >= 0; j--) //除法
        {
            temp = carry*10 + a[i][j];
            a[i][j] = temp/(i+1);
            carry = temp%(i+1);
        }
        while(!a[i][len-1])     //高位零处理
            len --;
        b[i] = len;
    }
}

int main()
{
    int i, n;
    catalan();
    while(cin>>n)
    {
        for(i = b[n]-1; i>=0; i--)
        {
            cout<<a[n][i];
        }
        
        cout<<endl;
    }

    return 0;
}


你可能感兴趣的:(【新年新气象_1】卡特兰(Catalan)数入门及应用)