卡特兰数(代码)

数列前几项: 1 , 1 , 2 , 5 , 14 , 42 , 132 , 429 , 1430... 1, 1, 2, 5, 14, 42, 132, 429, 1430... 1,1,2,5,14,42,132,429,1430...
满足递推式: C n = C 0 ∗ C n − 1 + C 1 ∗ C n − 2 + . . . + C n − 2 ∗ C 1 + C n − 1 ∗ C 0 ( n > = 2 ) C_n= C_0*C_{n-1}+C_1*C_{n-2} + ... + C_{n-2}*C_1+C_{n-1}*C_0 (n>=2) Cn=C0Cn1+C1Cn2+...+Cn2C1+Cn1C0(n>=2)
递推关系的另类解为:

1. C n = ( 4 n − 2 ) ∗ C n − 1 n + 1 C_n=\frac {(4n-2)*C_{n-1}}{n+1} Cn=n+1(4n2)Cn1

2. C n = C ( 2 n , n ) ( n + 1 ) ( n = 0 , 1 , 2 , . . . ) C_n=\frac {C(2n,n)}{(n+1) }(n=0,1,2,...) Cn=(n+1)C(2n,n)(n=0,1,2,...)

3. C n = C ( 2 n , n ) − C ( 2 n , n − 1 ) ( n = 0 , 1 , 2 , . . . ) C_n=C(2n,n)-C(2n,n-1)(n=0,1,2,...) Cn=C(2n,n)C(2n,n1)(n=0,1,2,...)

应用:

1.矩阵连乘: P=a1×a2×a3×……×an,依据乘法结合律,不改变其顺序,只用括号表示成对的乘积,试问有几种括号化的方案?(h(n)种)
2.一个栈(无穷大)的进栈序列为1,2,3,…,n,有多少个不同的出栈序列?(f(n)=h(n))
3.在一个凸多边形中,通过若干条互不相交的对角线,把这个多边形划分成了若干个三角形。任务是键盘上输入凸多边形的边数n,求不同划分的方案数f(n)。(f(n)=h(n-2)(n=2,3,4,5,6,7…))
4.给定N个节点,能构成多少种不同的二叉搜索树?(h(n)个)
5.给定n对括号,求括号正确配对的字符串数(h(n)种)

35以内可以用公式1递推推出来,不会爆long long.
代码:(100以内的)

int a[101][101];//可以把a[i]看成第i个卡特兰数,需要倒序输出
int b[101];//b[i]表示第i个卡特兰数的长度;
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()
{
    catalan();
    for(int i=1;i<=100;i++){
        for(int j=b[i]-1;j>=0;j--)
        cout<<a[i][j];
        cout<<endl;
    }
    return 0;
}
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值