题目描述
X 星球特别讲究秩序,所有道路都是单行线。
一个甲壳虫车队,共 16 辆车,按照编号先后发车,夹在其它车流中,缓缓前行。
路边有个死胡同,只能容一辆车通过,是临时的检查站,如图所示。
X 星球太死板,要求每辆路过的车必须进入检查站,也可能不检查就放行,也可
能仔细检查。
如果车辆进入检查站和离开的次序可以任意交错。
那么,该车队再次上路后,可能的次序有多少种?
为了方便起见,假设检查站可容纳任意数量的汽车。
显然,如果车队只有 1 辆车,可能次序 1 种;2 辆车可能次序 2 种;3 辆车可能
次序 5 种。
现在足足有 16 辆车啊,亲!需要你计算出可能次序的数目。
解法一
解题思路
动态规划
设f(n)表示,有n辆车时的所有可能次序数目,则:
f(1) = 1 // 1
f(2) = 2 // 1,2; 2,1
f(3) = 5 // 1,2,3; 1,3,2; 2,1,3; 2,3,1; 3,2,1
f(4)时,设有a,b,c,d辆车,a有四种出栈可能
1.a第一个出栈,此时还有b,c,d辆车在 后面出栈,即为子问题f(3)
2.a第二个出栈,那么b比a先出栈,即f(1),c,d比a后出栈,即f(2),故最终数目为f(1)*f(2)
3.a第三个出栈那么b,c比a先出栈,即f(2),d比a后出栈,即f(1),故最终数目为f(2)*f(1)
4.a第四个出栈,有b,c,d辆车比a先出栈,即子问题f(3)
故f(4) = f(3) + f(1)*f(2) + f(2)*f(1) + f(3)
可推的递推公式:f(n) = f(n-1) + f(1)*f(n-2) +...+ f(n-2)*f(1) + f(n-1)
可写为C(2n,n)/(n+1)
python代码
#出栈次序,答案35357670
def solution(n):
dp = [1,1,2,5]
if n <= 3:
return dp[n]
for i in range(4,n+1):
tmp = 0
for j in range(i):
tmp += dp[j]*dp[i-j-1]
dp.append(tmp)
return dp[-1]
if __name__ == "__main__":
n = 16
ans = solution(n)
print(ans)
运行结果
java代码
package 蓝桥杯训练营第一周作业;
/*出栈次序,答案35357670*/
public class homework03 {
private static int solution(int n) {
int[] dp = new int[n+1];
int i,j,tmp;
dp[0] = 1; dp[1] = 1; dp [2] = 2; dp[3] = 5;
for(i = 4; i <= n; i++) { //初始dp
dp[i] = 0;
}
if(n <= 3)
return dp[n];
for (i = 4; i <= n; i++) {
tmp = 0;
for (j = 0;j < i; j++)
tmp += dp[j]*dp[i-j-1];
dp[i] = tmp;
}
return dp[n];
}
public static void main(String[] args) {
int n,ans;
n = 16;
ans = solution(n);
System.out.println(ans);
}
}