1. 程式人生 > >卡特蘭數列(Catalan)

卡特蘭數列(Catalan)

【概述】

卡特蘭數列是組合數學中一個常出現在各種計數問題中出現的數列,其前幾項為 : 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, ......

卡特蘭數首先是由尤拉在計算對凸 n 邊形的不同的對角三角形剖分的個數問題時得到的。 

問題:在一個凸 n 邊形中,通過不相交於 n 邊形內部的對角線,把 n 邊形拆分成若干三角形,不同的拆分數目用 Hn 表示,Hn即為卡特蘭數。

例如,五邊形有如下五種拆分方案,故H5=5。

【公式】

1.遞迴公式 1

f(n)=\sum_{i=0}^{n-1}f(i)*f(n-i-1)

2.遞迴公式 2

f(n)=f(n-1)*(4*n-2)/(n+1)

3.組合公式 1

f(n)=C_{2n}^n/(n+1)

4.組合公式 2

f(n)=C_{2n}^n-C^{n-1}_{2n}

【應用】

  1. 二叉樹的計數:已知二叉樹有 n 個結點,求能構成多少種不同的二叉樹
  2. 括號化問題:一個合法的表示式由()包圍,()可以巢狀和連線,如:(())()也是合法表示式,現給出 n 對括號,求可以組成的合法表示式的個數
  3. 劃分問題:將一個凸 n+2 多邊形區域分成三角形區域的方法數
  4. 出棧問題:一個棧的進棧序列為1,2,3,..n,求不同的出棧序列有多少種
  5. 路徑問題:在 n*n 的方格地圖中,從一個角到另外一個角,求不跨越對角線的路徑數有多少種
  6. 握手問題:2n 個人均勻坐在一個圓桌邊上,某個時刻所有人同時與另一個人握手,要求手之間不能交叉,求共有多少種握手方法

【演算法實現】

/*
	函式功能:計算Catalan的第n項  
	函式引數:n為項數  
	返回值:第n個Catalan數
*/
int Catalan(int n)  
{  
    if(n<=1)  
        return 1;  
  
    int *H=new int [n+1]; //儲存臨時結果  
    H[0]=H[1]=1;//H(0)和H(1)  
    
    for(int i=2;i<=n;i++)//依次計算H(2),H(3)...H(n)  
    {  
        H[i]=0;  
        for(int j=0;j<i;j++)//根據遞迴式計算H(i)=Hh(0)*H(i-1)+H(1)*H(i-2)+...+H(i-1)H(0)  
            H[i]+=(H[j]*H[i-1-j]);  
    }  
    
    int result=H[n];//儲存結果  
    delete [] H;//釋放空間  
    return result;
}