1330 出棧序列統計 卡特蘭數

2021-08-22 08:46:32 字數 2607 閱讀 9817

題目描述:

按照1,2,...,n-1,n的順序入棧,問可以得到多少種出棧序列。如n=3時有1 2 3,1 3 2,2 1 3,2 3 1,3 2 1共5種出棧序列。

解題思路:

設f(n)為n個數時的方案數。

可知 f(0)=1; f(1)=1; f(2)=2;  f(3)=5;

當n=4時 :

f1    f2    f3    f4

1  2  3  4  //四種狀態分別標記為f1,f2,f3,f4

若f1 位於一號位置 則之前的數字出棧順序的情況數為f(0),在一號位置後的數字出棧順序的情況數為f(3);

則f1 位於一號位置時方案總數為f(0)*f(3);

若f1 位於二號位置 則f1之前的位置的數字出棧順序的情況數可知為f(1),在二號位置之後的數字的出棧順序為f(2)。

則f1位於二號位置時方案總數為f(1)*f(2);

同理:f1位於三號位置時 方案數為 f(2)*f(1);

f1位於四號位置時 方案數為f(3)*f(0);

由上述條件可以推出:

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

則當n未知時由以上結論可推:

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

以上就是本題的一般遞推式,我們會發現 這個式子的實際時間複雜度為o(n^2);

當然不是很快,於是我們引入 卡特蘭數;

所謂卡特蘭數 就是 當遞推式中出現h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n>=2)時,

可知代數式的解為h(n)=c(2n,n)/(n+1) (n=0,1,2,...);

於是乎我們的式子就化簡為了f(n)=f(n-1)*(4*n-2)/(n+1)

對於出棧序列中的每乙個數字,在它後面的、比它小的所有數字,一定是按遞減順序排列的。

比如入棧順序為:1 2 3 4。

出棧順序:4 3 2 1是合法的,對於數字 4 而言,比它小的後面的數字是:3 2 1,且這個順序是遞減順序。同樣地,對於數字 3 而言,比它小的後面的數字是: 2 1,且這個順序是遞減的。....

出棧順序:1 2 3 4 也是合法的,對於數字 1 而言,它後面沒有比它更小的數字。同樣地,對於數字 2 而言,它後面也沒有比它更小的數字。

出棧順序:3 2 4 1 也是合法的,對於數字 3 而言,它後面比 3 小的數字有: 2 1,這個順序是遞減的;對於數字 2 而言,它後面的比它 小的數字只有 1,也算符合遞減順序;對於數字 4 而言,它後面的比它小的數字也只有1,因此也符合遞減順序。

出棧順序:3 1 4 2 是不合法的,因為對於數字 3 而言,在3後面的比3小的數字有:1 2,這個順序是乙個遞增的順序(1-->2)。

因此,當給定乙個序列時,通過這個規律 可以輕鬆地判斷 哪些序列是合法的,哪些序列是非法的。

答案是 卡特蘭數。即一共有:h(n)=c(2n,n)/(n+1) 種合法的出棧順序。

如果僅僅只需要求出一共有多少種合法的出棧順序,其實就是求出組合 c(2n,n)就可以了。而求解c(2n,n),則可以用動態規劃來求解

時間限制: 1 sec  記憶體限制: 128 mb

提交: 53  解決: 43

您該題的狀態:已完成

[提交][狀態][討論版]

棧是常用的一種資料結構,有n個元素在棧頂端一側等待進棧,棧頂端另一側是出棧序列。你已經知道棧的操作有兩種:push和pop,前者是將乙個元素進棧,後者是將棧頂元素彈出。現在要使用這兩種操作,由乙個操作序列可以得到一系列的輸出序列。請你程式設計求出對於給定的n,計算並輸出由運算元序列1,2,…,n,經過一系列操作可能得到的輸出序列總數。 

乙個整數n(1<=n<=15) 

乙個整數,即可能輸出序列的總數目。

3

5

先了解棧的兩種基本操作,進棧push就是將元素放入棧頂,棧頂指標上移一位,等待進棧佇列也上移一位,出棧pop是將棧頂元素彈出,同時棧頂指標下移一位。 

用乙個過程採模擬進出棧的過程,可以通過迴圈加遞迴來實現回溯:重複這樣的過程,如果可以進棧則進乙個元素,如果可以出棧則出乙個元素。就這樣乙個乙個地試探下去,當出棧元素個數達到n時就計數一次(這也是遞迴呼叫結束的條件)。 

資料結構

這道題,我剛開始還想著,玩個遞迴,沒想到程式崩潰,玩不起,後來,有人提醒用卡特蘭數,我一搜,數學好的,就是不一樣。

#include

#include

using namespace std;

int main()

;for(i=4;i<20;i++)

a[i]=a[i-1]*(4*i-2)/(i+1);

cin>>n;

printf("%lld\n",a[n]);

return 0;

}

出棧 記憶搜尋 卡特蘭數

1.用dfs來做,記錄以備用 1 include2 include3 include4 include5 include6 include7 include8 define mem a memset a,0,sizeof a 9using namespace std 10long f 20 20 1...

卡特蘭數 算出棧的序列數

卡特蘭數 24 問題描述 12個高矮不同的人,排成兩排,每排必須是從矮到高排列,而且第二排比對應的第一排的人高,問排列方式有多少種?這個筆試題,很yd,因為把某個遞迴關係隱藏得很深.問題分析 我們先把這12個人從低到高排列,然後,選擇6個人排在第一排,那麼剩下的6個肯定是在第二排.用0表示對應的人在...

棧和卡特蘭數(Catalan number)

棧是計算機中經典的資料結構,我們也會遇到乙個常見的問題 一共有多少種合法的出棧順序?先說一下什麼是合法的出棧序列,凡是合法序列都遵循以下規律 即對於出棧序列中的每乙個數字,在它後面的 比它小的所有數字,一定是按遞減順序排列的。例如 有數字1 2 3 4 依次入棧,那麼他們的出棧順序中 所以到底有多少...