出栈序列统计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1 2 3 回专题模式 回学习阶段模式
【题目名称、来源】
【问题背景】栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表。
栈有两种最重要的操作,即pop (从栈顶弹出一个元素)和push (将一个元素进栈)。 栈的重要性不言自明,任何一门数据结构的课程都会介绍栈。宁宁同学在复习栈的基本概念时,想到了一个书上没有讲过的问题,而他自己无法给出答案,所以需要你的帮忙。
【问题描述】
输出序列 尾端 头端 操作数序列
头端
栈A
宁宁考虑的是这样一个问题:一个操作数序列,从1,2,一直到n (图示为1到3的情况),栈A 的深度大于n 。
现在可以进行两种操作,
1.将一个数,从操作数序列的头端移到栈的头端(对应数据结构栈的push 操作)
2. 将一个数,从栈的头端移到输出序列的尾端(对应数据结构栈的pop 操作)
使用这两种操作,由一个操作数序列就可以得到一系列的输出序列,下图所示为由1 2 3生成序列2 3 1的过程。(原始状态如上图所示)
你的程序将对给定的n ,计算并输出由操作数序列1,2,…,n 经过操作可能得到的输出序列的总数。
【输入格式】
输入文件只含一个整数n (1≤n ≤18)
【输出格式】
1
2 3 1 2 3 1
3
2 1 1
3
2 2
3 2 3 1
输出文件只有一行,即可能输出序列的总数目
【输入样例】
3
【输出样例】
5
【所属专题】
【适合学习阶段】
【解题思路】
问题分析:方法一、递归模拟出栈顺序。方法二、找递推式,可知出栈序列总数为catalan 数
方法二:
设f(n)表示有n 节车厢的出站的方法数
那么,第1节车厢显然有进栈和不进栈两种方法.
不进栈的方法为f(n-1)
进栈的方法数,可以归结为元素1第i 次出栈的所有可能性。
元素1排列在第i 个位置,那么将整个序列分裂为2~i ,1,i+1~n 两个部分。显然
方法数为两个部分之积,如下:
这种方法可以说是动态规划,但是也可以说是利用了组合数学中的加法原理、程法原理。 方法三:catalan 数
设某个数字i 进栈的为1,出栈为0,不入栈直接到达目标为10,则很明显对于出栈序列所对应的01串中,从左到右扫描的时候,1的个数总是不小于0的个数,所以问题等同于catalan 数。
存储结构:
【测试数据】
【源程序】
递归程序
program StackNumber;
var
st:array[1..3,0..100] of integer;
count,n,i:integer;
∑=--n
f i n f i f 21
)0(),(*)1(其中∑∑=--==>=--+-=n n
f i n f i f n f f i n f i f n f n f 121
)0(),(*)1()(1
)0(),(*)1()1()(其中其中所以,
procedure try;
begin
if st[3,0]=n then begin
count:=count+1;
for i:=1 to n do write(st[3,i],' ');
writeln;
end
else begin
if st[1,0]>0 then begin
st[2,0]:=st[2,0]+1;
st[2,st[2,0]]:=st[1,st[1,0]];
st[1,0]:=st[1,0]-1;
try;
st[1,0]:=st[1,0]+1;
st[1,st[1,0]]:=st[2,st[2,0]];
st[2,0]:=st[2,0]-1;
end;
if st[2,0]>0 then begin
st[3,0]:=st[3,0]+1;
st[3,st[3,0]]:=st[2,st[2,0]];
st[2,0]:=st[2,0]-1;
try;
st[2,0]:=st[2,0]+1;
st[2,st[2,0]]:=st[3,st[3,0]];
st[3,0]:=st[3,0]-1;
end;
end;
end;
begin
count:=0;n:=4;
for i:=n downto 1 do st[1,n-i+1]:=i; st[1,0]:=n;
try;
writeln(count);
end.