1. 程式人生 > >catalan數 出棧序列

catalan數 出棧序列

1.飯後,姐姐洗碗,妹妹把姐姐洗過的碗一個一個地放進碗櫥摞成一摞。一共有n個不同的碗,洗前也是摞成一摞的,也許因為小妹貪玩而使碗拿進碗櫥不及時,姐姐則把洗過的碗摞在旁邊,問:小妹摞起的碗有多少種可能的方式?

2.給定n個數,有多少種出棧序列?

3.一個有n個1和n個-1組成的字串,且前k個數的和均不小於0,那這種字串的總數為多少?

這三個問題具有相同的結構,三個問題是可以互相轉化。將姐姐放碗看做入棧操作,將妹妹放碗看做出棧操作。則問題一變為問題二。將入棧操作記為1,出棧記為-1,問題2變為問題3。

問題的答案是一個著名的數列,卡特蘭數。該問題的代數解法比較抽象,而運用到幾何上,用圖片來描述,卻有讓人恍然大悟的感覺。

    事實上,可以認為問題是,任意兩種操作,要求每種操作的總次數一樣,且進行第k次操作2前必須先進行至少k次操作1。我們假設一個人在原點,操作1是此人沿右上角45°走一個單位(一個單位設為根號2,這樣他第一次進行操作1就剛好走到(1,1)點),操作2是此人沿右下角45°走一個單位。第k次操作2前必須先進行至少k次操作1,就是說明所走出來的折線不能跨越x軸走到y=-1這條線上!在進行n次操作1和n此操作2後,此人必將到到達(2n,0)!若無跨越x軸的限制,折線的種數將為C(2n,n),即在2n次操作中選出n次作為操作1的方法數。


現在只要減去跨越了x軸的情況數。對於任意跨越x軸的情況,必有將與y=-1相交。找出第一個與y=-1相交的點k,將k點以右的折線根據y=-1對稱(即操作1與操作2互換了)。可以發現終點最終都會從(2n,0)對稱到(2n,-2)。由於對稱總是能進行的,且是可逆的。我們可以得出所有跨越了x軸的折線總數是與從(0,0)到(2n,-2)的折線總數。而後者的操作2比操作1要多0-(-2)=2次。即操作1為n-1,操作2為n+1。總數為C(2n,n-1)。


catalan數和出棧序列的對應:

動態規劃:我們把n個元素的出棧個數的記為f(n), 那麼對於1,2,3, 我們很容易得出:

f(1) = 1     //即 1

f(2) = 2    //即 12、21

                                     f(3) = 5     //即 123、132、213、321、231

然後我們來考慮f(4), 我們給4個元素編號為a,b,c,d, 那麼考慮:元素a只可能出現在1號位置,2號位置,3號位置和4號位置(很容易理解,一共就4個位置,比如abcd,元素a就在1號位置)。

分析:

 1) 如果元素a在1號位置,那麼只可能a進棧,馬上出棧,此時還剩元素b、c、d等待操作,就是子問題f(3);

 2) 如果元素a在2號位置,那麼一定有一個元素比a先出棧,即有f(1)種可能順序(只能是b),還剩c、d,即f(2),     根據乘法原理,一共的順序個數為f(1) * f(2);

 3) 如果元素a在3號位置,那麼一定有兩個元素比1先出棧,即有f(2)種可能順序(只能是b、c),還剩d,即f(1),

    根據乘法原理,一共的順序個數為f(2) * f(1);

 4) 如果元素a在4號位置,那麼一定是a先進棧,最後出棧,那麼元素b、c、d的出棧順序即是此小問題的解,即         f(3);

結合所有情況,即f(4) = f(3) + f(2) * f(1) + f(1) * f(2) + f(3);

為了規整化,我們定義f(0) = 1;於是f(4)可以重新寫為:

f(4) = f(0)*f(3) + f(1)*f(2) + f(2) * f(1) + f(3)*f(0)

然後我們推廣到n,推廣思路和n=4時完全一樣,於是我們可以得到:

f(n) = f(0)*f(n-1) + f(1)*f(n-2) + ... + f(n-1)*f(0)