X星球特別講究秩序,所有道路都是單行線。一個甲殼蟲車隊,共16輛車,按照編號先後發車,夾在其它車流中,緩緩前行。
路邊有個死衚衕,只能容一輛車通過,是臨時的檢查站,如圖【p1.png】所示。
X星球太死板,要求每輛路過的車必須進入檢查站,也可能不檢查就放行,也可能仔細檢查。
如果車輛進入檢查站和離開的次序可以任意交錯。那麼,該車隊再次上路後,可能的次序有多少種?
爲了方便起見,假設檢查站可容納任意數量的汽車。
顯然,如果車隊只有1輛車,可能次序1種;2輛車可能次序2種;3輛車可能次序5種。
現在足足有16輛車啊,親!需要你計算出可能次序的數目。
思路:知道卡特蘭數的這題可以直接推導出來。不知道也沒關係。稍微分析一下也簡單。求出棧次序,無非就是問一共有多少種滿足要求的排列,滿足條件在本題中就是指,只有站中有“車”,才能夠出來。假設1,代表進站,0代表出站,出站符合要求的就是指NUM(1)>=NUM(0)。最後生成的01排列就是總數。
方法一:按照邏輯求解,運用遞歸,耗時較長,約22秒
代碼:
import java.util.*;
public class Main {
public static int count = 0;
public static int n = 0;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
n = in.nextInt();
List<String> a = new ArrayList<String>();
for(int i=1; i<=n; i++) {
a.add(i + "");
}
f(a, new ArrayList<String>(), new ArrayList<String>());
System.out.println(count);
in.close();
}
public static void f(List<String> a, List<String> b, List<String> c) {
if(c.size() == n) {
count ++;
return;
}
if(b.size() == 0) {
List<String> b1 = new ArrayList<String>(b);//用新的List傳遞
List<String> a1 = new ArrayList<String>(a);
b1.add(a1.get(a1.size()-1));
a1.remove(a1.size()-1);
f(a1, b1, c);
return;
}
if(a.size() == 0) {
List<String> b1 = new ArrayList<String>(b);
List<String> c1 = new ArrayList<String>(c);
c1.add(b1.get(b1.size()-1));
b1.remove(b1.size()-1);
f(a, b1, c1);
return;
}
List<String> a1 = new ArrayList<String>(a);
List<String> b1 = new ArrayList<String>(b);
b1.add(a1.get(a1.size()-1));
a1.remove(a1.size()-1);
f(a1, b1, c);
List<String> b2 = new ArrayList<String>(b);
List<String> c2 = new ArrayList<String>(c);
c2.add(b2.get(b2.size()-1));
b2.remove(b2.size()-1);
f(a, b2, c2);
}
}
方法二:根據車數遞增,可能的次序數滿足Catalan數,用Catalan數公式求解
代碼:
public class Main {
public static void main(String[] args) {
int num = 1;
for(int i=1;i<=16;i++) {
num = num*(4*i-2)/(i+1);
}
System.out.println(num);
}
}