2014年第五屆藍橋杯C/C++程式設計本科B組決賽 出棧次序(結果填空)
2014年第五屆藍橋杯C/C++程式設計本科B組決賽題目彙總:
出棧次序
X星球特別講究秩序,所有道路都是單行線。一個甲殼蟲車隊,共16輛車,按照編號先後發車,夾在其它車流中,緩緩前行。路邊有個死衚衕,只能容一輛車通過,是臨時的檢查站,如圖【p1.png】所示。
X星球太死板,要求每輛路過的車必須進入檢查站,也可能不檢查就放行,也可能仔細檢查。
如果車輛進入檢查站和離開的次序可以任意交錯。那麼,該車隊再次上路後,可能的次序有多少種?
為了方便起見,假設檢查站可容納任意數量的汽車。
顯然,如果車隊只有1輛車,可能次序1種;2輛車可能次序2種;3輛車可能次序5種。
現在足足有16輛車啊,親!需要你計算出可能次序的數目。
題意:求n個元素的出棧情況有多少種。
思路:
方法一:
我們把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)
即
方法二:Catalan數:C(2n,n)/(n+1) (C(2n,n)表示2n裡取n)或者C(2n,n)-C(2n,n-1)都可以解決。
答案:35357670
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
int f[20];
memset(f,0,sizeof(f));
f[0]=1;
f[1]=1;
f[2]=2;
f[3]=5;
for(int i=4; i<=16; i++)
{
for(int j=0; j<=i-1; j++)
f[i]+=f[j]*f[i-1-j];
}
cout<<f[16]<<endl;
return 0;
}