hdu 1023 Train Problem II (卡特兰数)

7 篇文章 0 订阅

卡特兰数又称卡塔兰数,英文名Catalan number,是组合数学中一个常出现在各种计数问题中出现的数列

令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)

例如:h(2)=h(0)*h(1)+h(1)*h(0)=1*1+1*1=2         h(3)=h(0)*h(2)+h(1)*h(1)+h(2)*h(0)=1*2+1*1+2*1=5

另类递推式h(n)=h(n-1)*(4*n-2)/(n+1);

递推关系的解为:h(n)=C(2n,n)/(n+1) (n=0,1,2,...)

递推关系的另类解为:h(n)=c(2n,n)-c(2n,n-1)(n=0,1,2,...)

卡特兰数的应用:

1.括号化

  矩阵连乘: P=a1×a2×a3×……×an,依据乘法结合律,不改变其顺序,只用括号表示成对的乘积,试问有几种括号化的方案?(h(n-1)种)

         2.出栈次序

             一个栈(无穷大)的进栈序列为1,2,3,…,n,有多少个不同的出栈序列?

    3.凸多边形三角划分

          在一个凸多边形中,通过若干条互不相交的对角线,把这个多边形划分成了若干个三角形。任务是键盘上输入凸多边形的边数n,求不同划分的方案数f(n)

   4.给定节点组成二叉树

          给定N个结点,能构成多少种不同的二叉树(能构成h(N)个)


那么这个题显然属于第二类问题,由于n<=100,所以我们要用高精度来做

#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

int n,ans;
int h[105][1005];

void work(int n)
{
    int m=4*n-2;
    for (int i=1;i<=h[n-1][0];i++) h[n][i]=h[n-1][i]*m;
    int i;
    for (i=1;i<=h[n-1][0];i++)
    {
        h[n][i+1]+=h[n][i]/10;
        h[n][i]=h[n][i]%10;
    }
    while (h[n][i])
    {
        h[n][i+1]+=h[n][i]/10;
        h[n][i]=h[n][i]%10;
        i++;
    }
    m=n+1;
    i--;
    int x=0;
    for (int j=i;j>0;j--)
    {
        int y=h[n][j]+x*10;
        h[n][j]=y/m;
        x=y%m;
    }
    while (!h[n][i]) i--;
    h[n][0]=i;
}

int main()
{
    memset(h,0,sizeof(h));
    h[0][0]=1; h[0][1]=1;
    h[1][0]=1; h[1][1]=1;
    for (int i=2;i<101;i++)  work(i);
    while (scanf("%d",&n)!=EOF)
    {
        for (int i=h[n][0];i>0;i--) printf("%d",h[n][i]);
        printf("\n");
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值