出栈序列统计

来源:互联网 发布:adobe系列软件下载 编辑:程序博客网 时间:2024/04/29 23:47

2.3 出栈序列统计

栈是常用的一种数据结构,有n个元素在栈顶端一侧等待进栈,栈顶端另一侧是出栈序列。你已经知道栈的操作有两种:pushpop,前者是将一个元素进栈,后者是将栈顶元素弹出。现在要使用这两种操作,由一个操作序列可以得到一系列的输出序列。请你编程求出对于给定的n,计算并输出由操作数序列12,…,n,经过一系列操作可能得到的输出序列总数。【问题描述】

【输入】 

就一个数n(①1<=n<=15   ②1n1000)。 

 【输出】

 一个数,即可能输出序列的总数目。

【样例】

stack.in 

3

stack.out

 5

①当n范围较小时,可以用回溯,也可以用递推(这是一个卡特兰数列);

回溯:将题意转化为:给出a、b、c三个栈,a是初状态,b是过渡状态,c是末状态,要把a中的元素最终全放到c中,有两种放法:1、从a中直接放到c中。2、先放到b中,再放到c中(当前元素,有两种选择,放到c中,或者暂时留在b中);

var n:byte;ans:longint;procedure init;  begin    readln(n);  end;procedure try(a,b,c,d:longint);//a、b、c三个栈,b表示第几种操作,1-从a中放入b中,2-从a中放入c中,3-从b中放入c中;  begin    if c=n then inc(ans);    if a<n then      begin        try(a+1,b+1,c,1);        try(a+1,b,c+1,2);      end;    if (b>0)and(d<>1) then try(a,b-1,c+1,3);  end;procedure main;  begin    ans:=0;    try(0,0,0,0);    writeln(ans);  end;begin assign(input,'stack.in');reset(input); assign(output,'stack.out');rewrite(output);  init;  main; close(input);close(output);end.
递推:笔算可知,当n为1,2,3时,答案分别为1,1,5;初步判断为卡特兰数,然后嘛。。。。zy曾经说过,凡是卡特兰数的问题都可以转化为一个模式,不过,我忘了,等哪天问问他,再添上吧。。。。

var n:integer;    f:array[0..1000]of longint;procedure init;  var i:integer;    begin      readln(n);      fillchar(f,sizeof(f),0);      f[1]:=1;f[2]:=1;f[3]:=5;    end;procedure main;  var i:integer;    begin      if n<=3 then        begin          writeln(f[n]);          close(input);close(output);          halt;        end;      for i:=4 to n do f[i]:=(f[i-1]*(4*i-2)) div (i+1);//卡特兰数通项;      writeln(f[n]);    end;begin assign(input,'stack.in');reset(input); assign(output,'stack.out');rewrite(output);  init;  main; close(input);close(output);end.
②当范围较大时,不但要用递推,还得加高精,顺便注意,开数组得开longint的,不然999过不了;

var n,len:integer;    f:array[0..100000]of longint;procedure init;  var i:integer;    begin      readln(n);      fillchar(f,sizeof(f),0);      f[1]:=1;f[2]:=1;f[3]:=5;    end;procedure gcheng(x:integer);  var i:integer;    begin      for i:=1 to len do f[i]:=f[i]*(4*x-2);      for i:=1 to len do        if f[i]>=10 then          begin            f[i+1]:=f[i+1]+f[i] div 10;            f[i]:=f[i] mod 10;          end;      while f[len+1]<>0 do        begin          inc(len);          f[len+1]:=f[len+1]+f[len] div 10;          f[len]:=f[len] mod 10;        end;    end;procedure gchu(x:integer);  var i:integer;    begin      for i:=len downto 1 do        begin          f[i-1]:=f[i-1]+10*(f[i] mod x);          f[i]:=f[i] div x;        end;      while f[len]=0 do dec(len);    end;procedure main;  var i:integer;    begin      if n<=3 then        begin          writeln(f[n]);          close(input);close(output);          halt;        end;      f[1]:=5;f[2]:=0;f[3]:=0;len:=1;      for i:=4 to n do gcheng(i);      for i:=5 to n+1 do gchu(i);      for i:=len downto 1 do write(f[i]);    end;begin assign(input,'stack.in');reset(input); assign(output,'stack.out');rewrite(output);  init;  main; close(input);close(output);end.