標準二維表問題

2022-02-23 06:31:49 字數 3631 閱讀 1899

問題描述:

設n 是乙個正整數。2xn的標準2維表是由正整數1,2,…,2n 組成的2xn 陣列,該陣列的每行從左到右遞增,每列從上到下遞增。2xn的標準2維表全體記為tab(n)。

例如,當n=3時tab(3)如下:

思路分析:首先明確一下每行的數總是左邊小於後面,上面小於下面,以上面的第一種情況進行分析,我們把第一行的數字對應為1表示進棧

。第二行的數字對應為-1表示出棧。我們知道一般情況進棧和出棧時棧裡面的元素個數大於等於0,那麼數字1看成進棧-1看成出棧,則總數之和要大於等於0。

即進出棧操作任何時刻進棧次數大於等於出棧的次數。那麼上表的第一行第乙個元素表示第一次是進棧操作,下面的4對應的是第一次進棧的元素在第四次出棧,第一行第二列2

表示第二次操作是進棧對應對應下面的5表示第五次操作是出棧,即把第二次進棧操作的元素出棧,依次類推,第三次是進棧操作,第六次把第三次進棧的元素彈出棧。

所以我們可以把錶看出是元素的進出棧的操作,則tab(n)表示求元素個數為n的所有可能進出棧的操作。於是問題轉換為n個元素所有可能進出棧的情況。

而求進出棧的所有可能情況的方法就是卡特蘭數。下面簡單介紹一下卡特蘭數。

事實上,可以認為問題是,任意兩種操作,要求每種操作的總次數一樣,且進行第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)

下面是推導式,不給證明了

另類遞推式:

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,...)

那麼我們了解了卡特蘭數之後就可以寫**了,demo如下

1 #include2

3using

namespace

std;

4int tan(int

n)1213}

14int

main()

15

但是這個**只是簡單運用了卡特蘭數解決了n較小的問題,但是如下

其前幾項為 : 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420, 24466267020, 91482563640, 343059613650, 1289904147324, 4861946401452, ...

所以n較大的時候int就無法表示,下面是處理大整數後的思路(關於大整數的內容可以我的參考這篇部落格(

下面是具體的大卡特蘭數

1 #include2

using

namespace

std;

3char array1[200];4

char array2[200];5

int sum[400];6

string f(string s1,string s2)//

大整數乘法721

}22int f=0;23

while(true)31

else34}

35string a="";36

int ig=0;37

for(int i=l1+l2-1;i>=0;i--)

41if(ig==1)44

}45return

a;46}47

string div(string a,int b)

58int j=0;59

string

as="";60

while(s[j]=='0'

)61 j++;

6263

for(;j)

64as+=s[j];//商65

returnas;

6667}68

int t(string n)//

把字串變為int型別

6976

return

a;77}78

string tan(string n)97}

98int

main()

99

標準二維表問題

問題描述 設n是乙個正整數,2 n的二維表是由正整數1,2,2n組成的2 n陣列,該陣列的每行從左到右遞增,每列從上到下遞增。這樣的陣列為標準二維表。輸入乙個整數n 0 輸入n輸出乙個整數 樣例輸入 3 樣例輸出 5遞迴的 利用遞迴時,我們基於入棧和出棧的思想來解決問題 1 如果元素出現在第乙個位置...

標準二維表問題 窮舉

問題描述 設n 是乙個正整數。2xn的標準2維表是由正整數1,2,2n 組成的2xn 陣列,該陣列的每行從左到右遞增,每列從上到下遞增。2xn的標準2維表全體記為tab n 例如,當n 3時tab 3 如下 演算法如下 include define max 100 using namespace s...

標準2 維表問題

標準2 維表問題 問題描述 n 是乙個正整數。2n 的標準2 維表是由正整數 1,2 2n 組成的2n 陣列,該 陣列的每行從左到右遞增,每列從上到下遞增。2n 的標準2 維表全體記為tab n 例如,當n 3 時tab 3 如下 1 2 3 1 2 4 1 2 5 1 3 4 1 3 5 4 5 ...