1. 程式人生 > >卡特蘭數

卡特蘭數

ini bits clas cnblogs 操作 div esp class 序列

卡特蘭數是組合數學 常見的數列

主要有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-1),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("\n");
    }
    return 0;
}

  其他問題,自行找把

卡特蘭數