Train Problem II

轉載於:http://m.blog.csdn.net/blog/u011471397/11648721#

Train Problem II

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4667    Accepted Submission(s): 2548


Problem Description
As we all know the Train Problem I, the boss of the Ignatius Train Station want to know if all the trains come in strict-increasing order, how many orders that all the trains can get out of the railway.
 

Input
The input contains several test cases. Each test cases consists of a number N(1<=N<=100). The input is terminated by the end of file.
 

Output
For each test case, you should output how many ways that all the trains can get out of the railway.
 

Sample Input
1 2 3 10
 

Sample Output
1 2 5 16796
Hint
The result will be very large, so you may not process it by 32-bit integers.
 

Author
Ignatius.L
 
 
 
 
這是一道卡特蘭數的題目,我覺得還不錯,我一開始想要用遞推按照遞推的式子把它推出來的,long long int
 
不過現在覺得真的好搞笑,因爲50 就已經不行了,所以我們要用一個模擬的方法把它做出來才行,這個模板實
 
在是經典的,很不錯啊。
 
 
爲什麼要用卡特蘭數呢?
 
首先,我們設f(n)=序列個數爲n的出棧序列種數。同時,我們假定,從開始到棧第一次出到空爲止,這 段過程中出棧的序數最大的是k。特別地,如果棧直到整個過程結束時才空,則k=n
首次出空之前第一個出棧的序數k將1~n的序列分成兩個序列,其中一個是1~k-1,序列個數爲k-1,另外一個是k+1~n,序列個數是n-k。
此時,我們若把k視爲確定一個序數,那麼根據乘法原理,f(n)的問題就等價於——序列個數爲k-1的出棧序列種數乘以序列個數爲n - k的出棧序列種數,即選擇k這個序數的f(n)=f(k-1)×f(n-k)。而k可以選1到n,所以再根據加法原理,將k取不同值的序列種數相加,得到的總序列種數爲:f(n)=f(0)f(n-1)+f(1)f(n-2)+……+f(n-1)f(0)。
看到此處,再看看卡特蘭數的遞推式,答案不言而喻,即爲f(n)=h(n)= C(2n,n)/(n+1)= c(2n,n)-c(2n,n+1)(n=0,1,2,……)。
最後,令f(0)=1,f(1)=1。
 
 
我仔細看了百度全科的這段話,說的很對。
 
 
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int a[120][122];
int b[130];
int i,j,k,n;
void  catalan()
{
    int tem,len;
    a[1][0]=1;
    a[1][1]=1;
    a[2][0]=1;
    a[2][1]=2;
    len=1;
    for(i=3;i<=100;i++)
    {

       tem=0;
       for(j=1;j<=len;j++)
       {
          k=a[i-1][j]*(4*i-2)+tem;
          tem=k/10;
          a[i][j]=k%10;
       }
       while(tem)
       {
           len++;
           a[i][len]=tem%10;
           tem=tem/10;
       }
       for(j=len;j>=1;j--)
       {
           k=a[i][j]+tem*10;
           a[i][j]=k/(i+1);
           tem=k%(i+1);
       }
       while(!a[i][len])
       {
           len--;
       }
       a[i][0]=len;
    }
}
int main()
{

    catalan();
    while(scanf("%d",&n)!=EOF)
    {

        /*for(i=4;i<=n;i++)//h(n)=h(n-1)*(4*n-2)/(n+1);
        {
            //a[i]=a[i-1]*(4*i-2)/(n+1);
            //printf("%lld  %d\n",a[i],i);
            //h[i] = h[i-1] * (4*i-2) / (i+1) ;
        }
        printf("%lld\n",h[n]);*/
        for(i=a[n][0];i>=1;i--)
        {
            printf("%d",a[n][i]);
        }
        printf("\n");


    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章