題目描述:
按照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 依次入棧,那麼他們的出棧順序中 所以到底有多少...