出栈次序
X星球特别讲究秩序,所有道路都是单行线。
一个甲壳虫车队,共16辆车,按照编号先后发车,夹在其它车流中,缓缓前行。
路边有个死胡同,只能容一辆车通过,是临时的检查站,如图【p1.png】所示。
X星球太死板,要求每辆路过的车必须进入检查站,也可能不检查就放行,也可能仔细检查。
如果车辆进入检查站和离开的次序可以任意交错。那么,该车队再次上路后,可能的次序有多少种?
为了方便起见,假设检查站可容纳任意数量的汽车。
显然,如果车队只有1辆车,可能次序1种;2辆车可能次序2种;3辆车可能次序5种。
现在足足有16辆车啊,亲!需要你计算出可能次序的数目。
这是一个整数,请通过浏览器提交答案,不要填写任何多余的内容(比如说明性文字)。
看似很复杂,其实只是问给你一组数据有多少种出栈顺序,这一分析一下子简单了许多,应为已经有大神对这种出栈顺序进行总结,其实有一个公式可以用
推到过程如下:(仅供参考)
如果元素a在1号位置,那么只可能a进栈,马上出栈,此时还剩元素b、c、d等待操作,就是子问题f(3)
2) 如果元素a在2号位置,那么一定有一个元素比a先出栈,即有f(1)种可能顺序(只能是b),还剩c、d,即f(2)
3) 如果元素a在3号位置,那么一定有两个元素比1先出栈,即有f(2)种可能顺序(只能是b、c),还剩d,即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)
即
推导过程可以不太懂,但是记住 f(n) = f(0)*f(n-1) + f(1)*f(n-2) + … + f(n-1)*f(0) 就可以了,记住这个公式,出栈顺序一下简单了许多不需要深入进行计算,当然这只对计算出栈种类计算有用,如果需要深入计算的题目,就不能偷懒啦。
计算的过程如下:
# include <stdio.h>
int fun(int n )
{
int i,j ,sum=0;
i=0,
j=n;
if(n==1 || n==0)
{
return 1;
}
if(n==2)
{
return 2;
}
for(i=0 ;i<n;i++)
{
sum+=fun(i)*fun(n-i-1);
}
return sum ;
}
main ()
{
int i ;
scanf("%d",&i);
printf("%d",fun(i));
return 0;
}