1,题目
栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表。
栈有两种最重要的操作,即 pop(从栈顶弹出一个元素)和 push(将一个元素进栈)。
栈的重要性不言自明,任何一门数据结构的课程都会介绍栈。
宁宁同学在复习栈的基本概念时,想到了一个书上没有讲过的问题,而他自己无法给出答案,所以需要你的帮忙。
宁宁考虑的是这样一个问题:一个操作数序列,从 1,2,一直到 n,栈 A 的深度大于 n。
现在可以进行两种操作, 将一个数,从操作数序列的头端移到栈的头端(对应数据结构栈的 pu操作)。
将一个数,从栈的头端移到输出序列的尾端(对应数据结构栈的 pop 操作)。
使用这两种操作,由一个操作数序列就可以得到一系列的输出序列。
你的程序将对给定的 n,计算并输出由操作数序列 1,2,…,n 经过操作可能得到的输出序列的数。
输入格式
输入文件只含一个整数 n。
输出格式
输出文件只有一行,即可能输出序列的总数目。
样例
输入样例:
3
输出样例:
5
2,算法
该题用到了栈的pop和push操作,我们可以用f[i][j](i表示未准备进栈数目,j表示栈内数目)来表示当有i个数在栈外、j个数在栈内时可能输出序列的情况有多少种。
我们先进行预处理。当i==0时,表示所有数都在栈内,此时的输出序列只有一种情况,也就是将栈中的数一个个从栈内弹出
f[0][j] = 1
当j==0时,表示所有数都在排队等待入栈,栈内数目为零,此时只能进行进栈操作。
f[i][j] = f[i - 1][j + 1]
当j!=0时,表示栈中数目不为零,此时分为两种情况。
1,进栈操作,f[i - 1][j + 1], 准备进栈数目减一,栈内数目加一
2,出栈操作,f[i][j - 1], 准备进栈的数目不变,栈内数目减一
所以f[i][j] = f[i - 1][j + 1] + f[i][j - 1]
3,源码
#include<iostream>
using namespace std;
int f[20][20], n;
int main()
{
//第一个数i 表示未进栈数目
//第二个数j 表示栈内数目
cin >> n;
for(int j = 0; j <= n; j++)f[0][j] = 1; //表示所有数都在栈内,输出结果只有一种情况
for(int i = 1; i <= n; i++)
{
for(int j = 0; j <= n; j++)
{
if(j == 0)f[i][j] = f[i - 1][j + 1]; //j==0表示栈空,只能进行进栈操作
else f[i][j] = f[i - 1][j + 1] + f[i][j - 1]; //两种情况,进栈操作和出栈
}
}
cout << f[n][0];
}