標準二維表問題,catalan數的應用

問題描述
設n是一個正整數。2*n的標準二維表是由正整數1,2,…,2n組成的2*n數組,該數組的每行從左到右遞增,每列從上到下遞增。2*n的標準二維表全體記爲tab(n)。例如,當n=3時,tab(3)二維表如下圖所示。
1 2 3
4 5 6

1 2 4
3 5 6

1 2 5
3 4 6

1 3 4
2 5 6

1 3 5
2 4 6

編程任務
給定正整數n,試計算tab(n)中2*n二維表的個數。

分析
1. 先把2*n個數字排成一行來看(1~2*n 有序)。放到第一行的數字標記爲0,放到第二行的數字標記爲1,這樣就可以有一個01的序列,題目要求前面的數字比後面和下面的數字小,這樣可以轉換爲,序列前面每個數字前面0的個數要大於等於1的個數。
2. 就是求由左而右掃描由n個1和n個0組成的2n位二進制數,0的累計數不小於1的累計數的方案種數。
3. 這個數恰好是catalan數

算法實現

#include<iostream>
using namespace std;
int cantalan( int n){
    if(n == 0 || n == 1) return 1;
    else{
        return cantalan(n-1)*(4*n -2)/(n+1);
    }
};
int main()
{
    int size = 0;
    cin>>size;
    cout<<cantalan(size);
}

只能說cantalan數應用範圍太廣了,領教了。

附:catalan數應用:

令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,2,3,…,n,有多少個不同的出棧序列?

分析:
對於每一個數來說,必須進棧一次、出棧一次。我們把進棧設爲狀態‘1’,出棧設爲狀態‘0’。n個數的所有狀態對應n個1和n個0組成的2n位二進制數。由於等待入棧的操作數按照1‥n的順序排列、入棧的操作數b大於等於出棧的操作數a(a≤b),因此輸出序列的總數目=由左而右掃描由n個1和n個0組成的2n位二進制數,1的累計數不小於0的累計數的方案種數。
在2n位二進制數中填入n個1的方案數爲c(2n,n),不填1的其餘n位自動填0。從中減去不符合要求(由左而右掃描,0的累計數大於1的累計數)的方案數即爲所求。
不符合要求的數的特徵是由左而右掃描時,必然在某一奇數位2m+1位上首先出現m+1個0的累計數和m個1的累計數,此後的2(n-m)-1位上有n-m個 1和n-m-1個0。如若把後面這2(n-m)-1位上的0和1互換,使之成爲n-m個0和n-m-1個1,結果得1個由n+1個0和n-1個1組成的2n位數,即一個不合要求的數對應於一個由n+1個0和n-1個1組成的排列。

顯然,不符合要求的方案數爲c(2n,n+1)。由此得出輸出序列的總數目=c(2n,n)-c(2n,n+1)=c(2n,n)/(n+1)=h(n)。

類似問題 買票找零
有2n個人排成一行進入劇場。入場費5元。其中只有n個人有一張5元鈔票,另外n人只有10元鈔票,劇院無其它鈔票,問有多少中方法使得只要有10元的人買票,售票處就有5元的鈔票找零?(將持5元者到達視作將5元入棧,持10元者到達視作使棧中某5元出棧)

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