出栈序列统计

【问题背景】

今天是一个阳光明媚,风和日丽的好日子,猪爸爸和猪妈妈带着佩奇和乔治去海滩玩耍。佩奇突发奇想,给乔治出了这么一道题。

【问题描述】

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

乔治才两岁,没法解决这么难的问题。这时,你恰好从乔治身边经过,于是他向你求助,请你帮助他解决这个问题。

【输入】【输出】

就一个数n(1≤n≤1000)。       一个数,即可能输出序列的总数目。

【样例】

stack.in stack.out

3 5

【胡乱分析】

设a,b,c分别代表等待进栈元素个数,栈中元素个数,出栈元素个数。元素的总个数n=a+b+c。则c=n-a-b,所以,只要知道a和b的数值,就可以求出c。那么对于这些元素来说,存在以下操作:①既进栈又出栈②只进栈不出栈③只出栈不进栈,那么对于三种操作,等待进栈元素个数与栈中元素个数也会进行相应的变化。

.用f(a,b)表示从(a,b)变为(0,0)的所有移动方法。即f(n,0)。写出以下递归式

边界值:f(0,0)=1。

对于原题,起初有n个元素等待进栈,栈中有0个元素。即f(n,0)

代码如下:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cmath>
 5 #include<cstring>
 6 using namespace std;
 7 int n;
 8 int f(int a,int b)
 9 {
10     if(a == 0 && b == 0)
11         return 1;
12     else if(a > 0 && b > 0)
13         return f(a-1,b+1)+f(a,b-1);
14     else if(a > 0 && b == 0)
15         return f(a-1,b+1);
16     else if(a == 0)
17         return f(a,b-1);
18 }
19 int main()
20 {
21     scanf("%d",&n);
22     printf("%d",f(n,0));
23     return 0;
24 }

end。

原文地址:https://www.cnblogs.com/peppa/p/8503145.html

时间: 2024-10-02 05:24:03

出栈序列统计的相关文章

不要搜索,出栈序列统计

1627: 出栈序列统计 时间限制: 1 Sec  内存限制: 128 MB 题目描述 栈是常用的一种数据结构,有n令元素在栈顶端一侧等待进栈,栈顶端另一侧是出栈序列.你已经知道栈的操作有两·种:push和pop,前者是将一个元素进栈,后者是将栈顶元素弹出.现在要使用这两种操作,由一个操作序列可以得到一系列的输出序列.请你编程求出对于给定的n,计算并输出由操作数序列1,2,-,n,经过一系列操作可能得到的输出序列总数. 输入 一个整数n(1<=n<=15) 输出 一个整数,即可能输出序列的总数

vijos - P1122出栈序列统计 (卡特兰数)

P1122出栈序列统计 未递交 标签:NOIP普及组2003[显示标签] 描写叙述 栈是经常使用的一种数据结构,有n令元素在栈顶端一側等待进栈,栈顶端还有一側是出栈序列. 你已经知道栈的操作有两·种:push和pop,前者是将一个元素进栈,后者是将栈顶元素弹出.如今要使用这两种操作.由一个操作序列能够得到一系列的输出序列. 请你编程求出对于给定的n,计算并输出由操作数序列1,2,-.n.经过一系列操作可能得到的输出序列总数. 格式 输入格式 一个整数n(1<=n<=15) 输出格式 一个整数,

【回溯法】出栈序列统计

必三更起五更眠:最无益,莫过一日曝十日寒. [回溯法]出栈序列统计 时间限制: 1 Sec  内存限制: 128 MB提交: 17  解决: 11[提交][状态][讨论版] 题目描述 栈是常用的一种数据结构,有n令元素在栈顶端一侧等待进栈,栈顶端另一侧是出栈序列.你已经知道栈的操作有两·种:push和pop,前者是将一个元素进栈,后者是将栈顶元素弹出.现在要使用这两种操作,由一个操作序列可以得到一系列的输出序列.请你编程求出对于给定的n,计算并输出由操作数序列1,2,…,n,经过一系列操作可能得

Catalan数 &amp;&amp; 【NOIP2003】出栈序列统计

令h(1)=1, h(0)=1,catalan数满足递归式: h(n)=h(0)*h(n-1)+h(1)*h(n-2)+...+h(n-1)h(0) (n>=2) =C(2n, n)/(n+1) =h(n-1)*2(2n-1)/(n+1) 具体推导请百度,这里只需记得推导公式为h(n)=h(n-1)*2(2n-1)/(n+1)即可. 我们来说说这个的应用吧,从catalan数的定义递归定义可以看出,它是由自己 本身的一部分和n减去一部分 的和得到的,也就是说,有n个物品,1个物品进行操作1,n-

生成所有的出栈序列 (回溯法)

给定一个入栈序列,找出所有可能的出栈序列. 如入栈序列为 [1, 2, 3] 则可能的出栈序列为 : [ 3 2 1 ] [ 2 3 1 ] [ 2 1 3 ] [ 1 3 2 ] [ 1 2 3 ] 采用回溯法和递归统计所有可能的出栈序列. 当所有的入栈序列已经全部入栈后,则只能出栈 当栈为空时,只能进栈 当仍有入栈元素且栈不为空时,可以入栈,也可以出栈 入栈 -> 递归处理下一个入栈元素 -> 恢复未入栈状态 出栈 -> 将出栈元素添加到出栈序列 -> 递归处理下一个入栈元素

栈与队列问题1——出栈序列

问题描述:栈是常用的一种数据结构,有n个元素在栈顶端一侧等待进栈,栈顶端另一侧是出栈序列.你已经知道栈的操作有两种:push和pop,前者是将一个元素进栈,后者是将栈顶元素弹出.现在要使用这两种操作,由一个操作序列可以得到一系列的输出序列.请你编程求出对于给定的n,计算并输出由操作数序列1,2,…,n,经过一系列操作可能得到的输出序列总数. 分析:之前就有看过这种问题.就是火车进站问题,判断序列是否合法,当时是用STL栈做的.这个题只需统计次数,那么,方法就十分简便了,递归和动归都可以实现,当然

给定入栈序列,求出合法的出栈序列的个数

思想:1.利用全排列函数next_permutation()求出所有可能的序列 2.从中选出所有正确的序列 #include <iostream> #include <stack> #include <vector> #include <algorithm> using namespace std; //判断序列是否是合法的出栈序列 bool IsPopOrder(const int* pPush,const int* pPop,int n) { if (p

栈-出栈序列正确性分析

问题很简单:在栈的性质下,1~n的数字按顺序入栈,给出它们的出栈序列,判定该序列是否合理. 相比于之前遇到过的“求解所有可行出栈序列”,本问题的复杂度着实降低了不少.不过要把这个过程正确地通过code模拟出来,在逻辑的处理上也需要注意不少细节. 下面先来讲讲处理的方法: 程序输入:n以及给定的出栈序列,出栈序列不妨设为q[n+1],其中q[1]~q[n]顺序保存正确性未知的出栈序列. 由于入栈是按顺序入栈,可以不用额外的数组保存,仅需要一个递增的标志A表示即可.同时,出栈序列也需要一个指针B来保

【C++】 出栈序列的合法性

之前我们对栈已经有所了解,先进后出,后进先出这是栈的两大特性,那么,我们经常会碰到这种题,例: 有一组元素abcdef,按先后顺序进栈,那么出栈时哪些情况是非法的? A.    fedcba B.    abdcef C.    acbdef D.    abcdef 选哪个呢??? 很明显,根据栈的两大特性:先进后出,后进先出,即可判断,答案:C 剖析: 先看C选项acb这样的出栈序列,那么进栈肯定是abc,那么显然出栈时c肯定不会在b之前,就这么简单.用代码实现这个合法性的判断,当然也是比较