卡特蘭數編程
大神解釋:https://blog.csdn.net/akenseren/article/details/82149145 權侵刪數組
原題
有一個容量足夠大的棧,n個元素以必定的順序入棧,出棧順序有多少種?spa
好比,AB兩個元素,入棧順序爲AB,出棧狀況有兩種:.net
(1)入A,出A,入B,出B,出棧順序爲AB;blog
(2)入A,入B,出B,出A,出棧順序爲BA。遞歸
所以,2個元素時,結果爲2。class
分析:設f(n)爲「n個元素以必定的順序入棧,出棧順序的種類數」。顯然f(1)=1,f(2)=2。咱們如今來分析通常狀況。通常狀況下,咱們能夠按照「第一個入棧的元素,在出棧序列中的位置」做爲分類手段。原理
舉個例子,咱們假設入棧元素爲A,B,C,D。咱們按照「A在出棧序列中的位置」分類討論:hack
(1)當A第一個出棧時,A先進,而後立刻出棧。這種狀況下,共有「BCD出棧順序的種類數」種方案。也就是f(n-1)。方法
(2)當A第二個出棧時,A先進,B再進,以後B須要立刻出來(這樣才能確保A排第二)。此時共有f(n-2)種方案。
(3)當A第三個出棧時,A先進,以後只要確保排在A後面兩個的元素比A先出便可。此時共有f(2)*f(n-3)種方案。f(2)是指「BC入棧出棧順序的種類數」,f(n-3)是指」D入棧出棧的種類數」。
……
分析到這裏,規律就很顯然了。
從第一項開始,分別是第一個入棧元素在第i+1個出棧的狀況數。
上式中,令f(0)=1 。
這個其實是卡特蘭數(Catalan number,又稱卡塔蘭數)。
若編程實現,須要維護一個一維數組,時間複雜度爲O(n^2)。(遞歸實現的時間複雜度過高)。
卡塔蘭數的通項公式爲h(n)=C(2n,n)-C(2n,n+1)(n=0,1,2,...)。
元素A、B、C、D依次進棧,寫出全部可能的出棧序列
應該有14種狀況
A第一個出棧:ABCD;ACBD;ACDB;ABDC;ADCB;
A第二個出棧:BACD;BADC;
A第三個出棧:CBAD;BCAD;
A第四個出棧:BCDA;CBDA;CDBA;BDCA;DCBA.
卡特蘭數
卡特蘭數前幾項爲 : 1, 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, ...
令h(0)=1,h(1)=1,catalan數知足遞推式: h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n>=2)
例如:h(2)=h(0)*h(1)+h(1)*h(0)=1*1+1*1=2
h(3)=h(0)*h(2)+h(1)*h(1)+h(2)*h(0)=1*2+1*1+2*1=5
另類遞推式: h(n)=h(n-1)*(4*n-2)/(n+1);
遞推關係的解爲: h(n)=C(2n,n)/(n+1) (n=1,2,3,...)
遞推關係的另類解爲: h(n)=c(2n,n)-c(2n,n+1)(n=1,2,3,...)
本題目的常規分析
首先,咱們設f(n)=序列個數爲n的出棧序列種數。同時,咱們假定第一個出棧的序數是k。
第一個出棧的序數k將1~n的序列分紅兩個序列,其中一個是1~k-1,序列個數爲k-1,另一個是k+1~n,序列個數是n-k。
此時,咱們若把k視爲肯定一個序數,那麼根據乘法原理,f(n)的問題就等價於——序列個數爲k-1的出棧序列種數乘以序列個數爲n - k的出棧序列種數,即選擇k這個序數的f(n)=f(k-1)×f(n-k)。而k能夠選1到n,因此再根據加法原理,將k取不一樣值的序列種數相加,獲得的總序列種數爲:f(n)=f(0)f(n-1)+f(1)f(n-2)+……+f(n-1)f(0)。
看到此處,再看看卡特蘭數的遞推式,答案不言而喻,即爲f(n)=h(n)= C(2n,n)/(n+1)= c(2n,n)-c(2n,n+1)(n=1,2,3,……)。
最後,令f(0)=1,f(1)=1。
很是規分析
問題等價於:n個1和n個0組成一2n位的2進制數,要求從左到右掃描,1的累計數不小於0的累計數,試求知足這條件的數有多少?【對於每個數來講,必須進棧一次、出棧一次。咱們把進棧設爲狀態‘1’,出棧設爲狀態‘0’】
解答: 設P2n爲這樣所得的數的個數。在2n位上填入n個1的方案數爲 C(n 2n)
不填1的其他n位自動填以數0。從C(n 2n)中減去不符合要求的方案數即爲所求。
不合要求的數指的是從左而右掃描,出現0的累計數超過1的累計數的數。
不合要求的數的特徵是從左而右掃描時,必然在某一奇數2m+1位上首先出現m+1個的累計數,和m個1的累計數。
此後的2(n-m)-1位上有n-m個1,n-m-1個0。如若把後面這部分2(n-m)-1位,0與1交換【就是0換成1 1換成0 不是順序的調換 是數值換】,使之成爲n-m個0,n-m-1個1,結果得 1個由n+1個0和n-1個1組成的2n位數,即一個不合要求的數對應於一個由n-1個0和n+1個1組成的一個排列。
咱們把進棧設爲狀態‘1’,出棧設爲狀態‘0’。【對於每個數來講,必須進棧一次、出棧一次】
因爲任意時刻,出棧的操做數必定不超過入棧的操做數
不符合要求的數的特徵是由左而右掃描時,必然在某一奇數位2m+1位上首先出現m+1個0的累計數和m個1的累計數,
【出棧數已經大於入棧數了】【由於合法的排列 不管在哪一個位置 1都是>=0的】【前面m個位置0、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組成的排列。
卡特蘭數 爲何要0 1 互換?【互換後的排列中0比1多1個,那麼無論怎麼排列,也都不合法】
相似問題 買票找零
1.有2n我的排成一行進入劇場。入場費5元。其中只有n我的有一張5元鈔票,另外n人只有10元鈔票,劇院無其它鈔票,問有多少中方法使得只要有10元的人買票,售票處就有5元的鈔票找零?(將持5元者到達視做將5元入棧,持10元者到達視做使棧中某5元出棧)
最終結果:C(2n,n)-C(2n,n+1)
2.