zoukankan      html  css  js  c++  java
  • 卡特兰数

    卡特兰数是组合数学 常见的数列

    主要有4种形式:

    1: h(n)= C 2n n /(n+1)
    2: h(n)= C 2n n - C 2n n-1
    3: h(n)= h(n-1)*(4*n-2) /(n+1)
    4: h(n)= h(0)*h(n-1)+h(1)*h(n-2)+...+h(n-1)*h(0)

    相当多的问题,虽然表面上看起来很不一样,但结果都是卡特兰数。

    HDU1023  train problem 2  讲火车 按编号1 2 3 。。。n 的顺序进站,  出站的序列数目有多少种?

    百度百科的解释两种,1:设k是最后出站的,那么编号小于k的 在k之前出站 , 编号大于k的 在k之前出站,两种情况互不干涉,符合乘法原理;设h(n)表示n列火车出站的序列种类数目,第k个出站的可能数目是:h(k-1)*h(n-k),h(n)就是对它的求和。

    第二种解释:n列火车,每列火车有两种选择,进站和出站,共有2n次操作,设进站为0,出站为1,可以用长度为2n的序列表示一种进出站方式。100100100100  ;序列中有n个1,n个0,根据问题知,想要出站,站内必须有火车,从左到右,0的数目>=1的数。  不符合要求的情况:从左到右,长2m的序列满足要求,且m个1,m个0,第2m+1个数是1。

    如果长为2n的二进制序列由n+1个1和n-1个0组成那么它一定是符合上面^要求,同样,依上述要求,将2m+1以后的0和1互换,则恰好构成n+1个1和n-1个0构成的序列。二者一一对应。数目是C2n  n-1

    是2式。

    卡特兰数前几项:

    h(1)=1;h(2)=2;h(3)=5;h(4)=14;h(5)=42;h(10)=16796;h(20)=6564120420;

    编程实现需要用高精度乘除法;实际上就是多项式乘除法。

    //four expression  :
    /*
        1: h(n)= C 2n  n  /(n+1)
        2: h(n)= C 2n  n - C 2n n-1
        3: h(n)= h(n-1)*(4*n-2) /(n+1)
        4: h(n)= h(0)*h(n-1)+h(1)*h(n-2)+...+h(n-1)*h(0)
    
        */
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=105;
    const int MOD=100000;
    int kate[maxn][maxn];
    void init()
    {
        kate[0][0]=1;
        kate[1][0]=1;
        kate[2][0]=2;
        for(int i=3;i<maxn;i++)
        {
            /******************
            multi
            */
            for(int j=0;j<maxn;j++)
                kate[i][j]=kate[i-1][j]*(4*i-2);
            for(int j=0;j<maxn-1;j++)
            {
                kate[i][j+1]+=kate[i][j]/MOD;
                kate[i][j]%=MOD;
            }
    
            int tmp=0;
            //***************************
            // division
            for(int j=maxn-1;j>=0;j--)
            {
                tmp=kate[i][j]+tmp*MOD;
                kate[i][j]=tmp/(i+1);
                tmp=tmp%(i+1);
            }
    
        }
    }
    int main()
    {
        init();
        int n;
        while(cin>>n)
        {
            int i;
            for(i=maxn-1;i>=0&&!kate[n][i];i--);
            printf("%d",kate[n][i]);
            for(i=i-1;i>=0;i-- )
                printf("%05d",kate[n][i]);
            printf("
    ");
        }
        return 0;
    }
    

      

    相关问题:二叉树的异构体数目

    推荐相关网址:http://blog.csdn.net/u010582082/article/details/69569237?locationNum=7&fps=1

    这里对卡特兰数的其他应用做了解释。

    其中这点写的有启发:分治法

    卡特兰数的递推公式是: 
    C(0)=1;C(1)=1; 
    C(n)=C(0)*C(n-1) + C(1)*C(n-2) + …… + C(n-1)C(0); 
    其实序列类场景也是可以用这种一般性方法求解的,大家有没有发现,无论是上面的排队问题,多边形分割问题,还是路径规划问题,它们都有一个共同点,就是初始状态一定是确定的,也就说,序列第一项是固定的,那么剩下的n-1项就可以用分治的思路分割成两个子序列去解决就可以了。抽象点概括下,就是对于问题A,规模为n,要解决这个问题,可以用分治的思想,首先固定其中某一个元素,将剩下的n-1个元素拆分成两个小问题,这两个小问题的规模分别是(0,n-1) (1,n-2) (2,n-3) … (n-1,0)。 
    卡特兰数表现了一种符合乘法原理事件的本性,某种程度上,反映了我们思考问题的方式,故而能够在许多场合得到应用。 

    落霞与孤鹜齐飞,秋水共长天一色
  • 相关阅读:
    C#路径中获取文件全路径、目录、扩展名、文件名称
    c#FTP应用---windows iis
    c#FTP应用---FileZilla Server
    在VS2010中使用Git管理源代码
    ABB机器人---PCSDK简介
    几款软件需求分析工具
    快速排序
    springmvc和struts2的区别比较
    Struts中ActionContext和ServletActionContext的比较
    设计模式--适配器模式
  • 原文地址:https://www.cnblogs.com/star-and-me/p/6882973.html
Copyright © 2011-2022 走看看