〖NOIP2003P〗栈
- 总时间限制:
- 5000ms
- 单个测试点时间限制:
- 1000ms
- 内存限制:
- 131072kB
- 描述
-
栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表。
栈有两种最重要的操作,即pop(从栈顶弹出一个元素)和push(将一个元素进栈)。
栈的重要性不言自明,任何一门数据结构的课程都会介绍栈。宁宁同学在复习栈的基本概念时,想到了一个书上没有讲过的问题,而他自己无法给出答案,所以需要你的帮忙。
宁宁考虑的是这样一个问题:一个操作数序列,从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)
- 输出
- 输出文件只有一行,即可能输出序列的总数目
- 样例输入
-
3
- 样例输出
-
5
- 来源
- NOIP原题
- 源程序:#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
using namespace std;
int sol[20][20],n;
int main(){
cin>>n;
for(int i=n;i>=0;i--)
for(int j=n;j>=0;j--){
if(i==n&&j==n) sol[i][j]=1;
else{
if(i<n) sol[i][j]=sol[i][j]+sol[i+1][j];
if(j<i) sol[i][j]=sol[i][j]+sol[i][j+1];
}
}
cout<<sol[0][0]<<endl;
return 0;
} - 分析:
考虑入和出的;那么如果ru==n&&chu==n就有解了,如果ru<n就可以进入,如果ru>chu就可以出,但是这样会超时,所以进行优化。
可有用递归递推,如果ru==n&&chu==n返回1,否则如果ru<n进入ans+=dfs(ru+1,chu),如果ru>chu出ans+=dfs(ru,chu+1),最终返回ans。
但是这样会超时,所以进行优化。
其实可以递推递归记忆化,那么就是如果i==n&&j==m,那么sol[i][j]=1;
否则就想上面一样
If(i<n) sol[i][j]+=sol[i+1][j];
If(j<i) sol[i][j]+=sol[i][j+1];