轉載:卡特蘭數

Catalan數——卡特蘭數 今天阿里淘寶筆試中碰到兩道組合數學題,感覺非常親切,但是筆試中失蹤推導不出來后來查了下,原來是Catalan數。悲劇啊,現在整理一下一、Catalan數的定義令h(1)=1,Catalan數滿足遞歸式:h(n) = h(1)h(n-1) + h(2)h(n-2) + ... + h(n-1)h(1),n>=2該遞推關系的解為:h(n) = C(2n-2,n-1)/n,n=1,2,3,...(其中C(2n-2,n-1)表示2n-2個中取n-1個的組合數)
問題描述:12個高矮不同的人,排成兩排,每排必須是從矮到高排列,而且第二排比對應的第一排的人高,問排列方式有多少種?
這個筆試題,很YD,因為把某個遞推關系隱藏得很深。
問題分析:
我們先把這12個人從低到高排列,然后,選擇6個人排在第一排,那么剩下的6個肯定是在第二排.
用0表示對應的人在第一排,用1表示對應的人在第二排,那么含有6個0,6個1的序列,就對應一種方案.比如000000111111就對應著第一排:0 1 2 3 4 5第二排:6 7 8 9 10 11010101010101就對應著第一排:0 2 4 6 8 10第二排:1 3 5 7 9 11問題轉換為,這樣的滿足條件的01序列有多少個。
觀察1的出現,我們考慮這一個出現能不能放在第二排,顯然,在這個1之前出現的那些0,1對應的人要么是在這個1左邊,要么是在這個1前面。而肯定要有一個0的,在這個1前面,統計在這個1之前的0和1的個數。也就是要求,0的個數大于1的個數。
OK,問題已經解決。如果把0看成入棧操作,1看成出棧操作,就是說給定6個元素,合法的入棧出棧序列有多少個。這就是catalan數,這里只是用于棧,等價地描述還有,二叉樹的枚舉、多邊形分成三角形的個數、圓括弧插入公式中的方法數,其通項是c(2n, n)/(n+1)。
在<<計算機程序設計藝術>>,第三版,Donald E.Knuth著,蘇運霖譯,第一卷,508頁,給出了證明:問題大意是用S表示入棧,X表示出棧,那么合法的序列有多少個(S的個數為n)顯然有c(2n, n)個含S,X各n個的序列,剩下的是計算不允許的序列數(它包含正確個數的S和X,但是違背其它條件)。在任何不允許的序列中,定出使得X的個數超過S的個數的第一個X的位置。然后在導致并包括這個X的部分序列中,以S代替所有的X并以X代表所有的S。結果是一個有(n+1)個S和(n-1)個X的序列。反過來,對一垢一種類型的每個序列,我們都能逆轉這個過程,而且找出導致它的前一種類型的不允許序列。例如XXSXSSSXXSSS必然來自SSXSXXXXXSSS。這個對應說明,不允許的序列的個數是c(2n, n-1),因此an = c(2n, n) - c(2n, n-1)。驗證:其中F表示前排,B表示后排,在枚舉出前排的人之后,對應的就是后排的人了,然后再驗證是不是滿足后面的比前面對應的人高的要求。

#include <iostream>  
using namespace std;  
  
int bit_cnt(int n)  
{  
    int result = 0;  
    for (; n; n &= n-1, ++result);  
    return result;  
}  
  
int main(void)  
{  
    int F[6], B[6];  
    int i,j,k,state,ok,ans = 0;  
    for (state = 0; state < (1 << 12); ++state)  
    {  
        if (bit_cnt(state) == 6)  
        {  
            i = j = 0;  
            for (int k = 0; k < 12; ++k)  
            {  
                if(state&(1<<k))  
                    F[i++] = k;  
                else  
                    B[j++] = k;  
            }  
            ok = 1;  
            for (k = 0; k < 6; ++k)  
            {  
                if (B[k] < F[k])  
                {  
                    ok = 0;  
                    break;  
                }  
            }  
            ans += ok;  
        }  
    }  
    cout << ans << endl;  
    return 0;  
}  

結果:132
而c(12, 6)/7 = 121110987/(765432) = 132
注意:c(2n, n)/(n+1) = c(2n, n) - c(2n, n-1)估計出題的人也讀過<<計算機程序藝術>>吧。PS:另一個很YD的問題:有編號為1到n(n可以很大,不妨在這里假定可以達到10億)的若干個格子,從左到右排列。在某些格子中有一個棋子,不妨設第xi格有棋子(1<=i<=k, 1<=k<=n)每次一個人可以把一個棋子往左移若干步,但是不能跨越其它棋子,也要保證每個格子至多只有一個棋子。兩個人輪流移動,移動不了的為輸,問先手是不是有必勝策略。三、Catalan數的典型應用:1、括號化問題。矩陣鏈乘: P=A1×A2×A3×……×An,依據乘法結合律,不改變其順序,只用括號表示成對的乘積,試問有幾種括號化的方案?
一個有n個X和n個Y組成的字串,且所有的部分字串皆滿足X的個數大于等于Y的個數。以下為長度為6的dyck words: XXXYYY XYXXYY XYXYXY XXYYXY XXYXYY 將上例的X換成左括號,Y換成右括號,Cn表示所有包含n組括號的合法運算式的個數: ((())) ()(()) ()()() (())() (()())
2、將多邊行劃分為三角形問題。將一個凸多邊形區域分成三角形區域(劃分線不交叉)的方法數?類似:在圓上選擇2n個點,將這些點成對連接起來使得所得到的n條線段不相交的方法數?


3、出棧次序問題。一個棧(無窮大)的進棧序列為1、2、3、...、n,有多少個不同的出棧序列?類似:有2n個人排成一行進入劇場。入場費5元。其中只有n個人有一張5元鈔票,另外n人只有10元鈔票,劇院無其它鈔票,問有多少中方法使得只要有10元的人買票,售票處就有5元的鈔票找零?(將持5元者到達視作將5元入棧,持10元者到達視作使棧中某5元出棧)類似:一位大城市的律師在他住所以北n個街區和以東n個街區處工作,每天她走2n個街區去上班。如果他從不穿越(但可以碰到)從家到辦公室的對角線,那么有多少條可能的道路?

分析:對于每一個數來說,必須進棧一次、出棧一次。我們把進棧設為狀態‘1’,出棧設為狀態‘0’。n個數的所有狀態對應n個1和n個0組成的2n位二進制數。由于等待入棧的操作數按照1‥n的順序排列、入棧的操作數b大于等于出棧的操作數a(a≤b),因此輸出序列的總數目=由左而右掃描由n個1和n個0組成的2n位二進制數,1的累計數不小于0的累計數的方案種數。4、給頂節點組成二叉樹的問題?! 〗o定N個節點,能構成多少種形狀不同的二叉樹?  (一定是二叉樹!先取一個點作為頂點,然后左邊依次可以取0至N-1個相對應的,右邊是N-1到0個,兩兩配對相乘,就是h(0)h(n-1) + h(2)h(n-2) + ...... + h(n-1)h(0)=h(n)) (能構成h(N)個)

在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組成的排列。
反過來,任何一個由n+1個0和n-1個1組成的2n位二進制數,由于0的個數多2個,2n為偶數,故必在某一個奇數位上出現0的累計數超過1的累計數。同樣在后面部分0和1互換,使之成為由n個0和n個1組成的2n位數,即n+1個0和n-1個1組成的2n位數必對應一個不符合要求的數。因而不合要求的2n位數與n+1個0,n-1個1組成的排列一一對應。顯然,不符合要求的方案數為c(2n,n+1)。由此得出輸出序列的總數目=c(2n,n)-c(2n,n+1)=1/(n+1)*c(2n,n)。(這個公式的下標是從h(0)=1開始的)
轉載自http://blog.csdn.net/hackbuteer1/article/details/7450250

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,786評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,656評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,697評論 0 379
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,098評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,855評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,254評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,322評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,473評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,014評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,833評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,016評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,568評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,273評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,680評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,946評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,730評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,006評論 2 374

推薦閱讀更多精彩內容