題目: ios
X星球特別講究秩序,全部道路都是單行線。
一個甲殼蟲車隊,共16輛車,按照編號前後發車,夾在其它車流中,緩緩前行。spa
路邊有個死衚衕,只能容一輛車經過,是臨時的檢查站,如圖所示。
X星球太死板,要求每輛路過的車必須進入檢查站,也可能不檢查就放行,也可能仔細檢查。
若是車輛進入檢查站和離開的次序能夠任意交錯。那麼,該車隊再次上路後,可能的次序有多少種?code
爲了方便起見,假設檢查站可容納任意數量的汽車。
顯然,若是車隊只有1輛車,可能次序1種;2輛車可能次序2種;3輛車可能次序5種。 blog
思路:這題說實話 ,惟一想到的是暴力,枚舉每一種可能的狀況,再判斷是否能夠行得通,可是很快就否決了,由於16個數的全排列根本數不清,16^16 太大了,而後沒什麼思路,看了it
題解,是這麼說的,其實就是找規律,下面具體看一下怎麼作出來的:io
咱們把n個元素的出棧個數的記爲f(n), 那麼對於1,2,3, 咱們很容易得出:class
f(1) = 1 //即 1stream
f(2) = 2 //即 十二、21原理
f(3) = 5 //即 12三、13二、21三、32一、231im
而後咱們來考慮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)
看代碼:
#include<iostream> #include<stack> #include<algorithm> using namespace std; typedef long long ll; const int maxn=100; ll a[maxn]; //f(n) = f(0)*f(n-1) + f(1)*f(n-2) + ... + f(n-1)*f(0) void solve(int x) { ll sum=0; for(int i=0;i<x;i++) sum+=a[i]*a[x-1-i]; a[x]=sum; } int main() { a[0]=1; a[1]=1; a[2]=2; a[3]=5; for(int i=4;i<=16;i++) solve(i); cout<<a[16]<<endl; return 0; }