这么说吧,网上的解释看着蛋疼,同一道题竟然每个页都是同一个答案?
看题: 求有容量限制的栈的出栈序列统计
题目描述
栈是常用的一种数据结构,它有两种操作:将一个元素进栈push和将栈顶元素弹出pop。现在有一个容量为m的栈S,有n个元素在栈S顶端一侧等待进栈,另一侧是出栈序列。现在要使用push和pop这两种操作,由一个操作序列可以得到一系列的输出序列。请你编程求出对于给定的n和m,计算并输出由操作数序列1,2,…,n,经过一系列操作可能得到的输出序列总数。
输入
两个数n,m(1≤n,m≤l000)。
输出
一个数,即可能输出序列的总数目除以4096的余数。
样例输入
3 2
样例输出
4
提示
有3个元素等待进栈,栈容量为2,通过栈操作后可得到的序列为(1,2,3),(1,3,2),(2,1,3),(2,3,1)4种。
30%的数据:1≤n≤20,1≤m≤20:
70%的数据:1≤n≤500,l≤m≤3001
100%的数据:1≤n≤2000,1≤m≤2000。
#include<iostream>
using namespace std;
#define MOD 4096
int dp[2016][2016];
int m,n;
int main()
{
scanf("%d%d",&n,&m);
for(int k=0;k<=n;k++)
dp[k][0] = 1;
for(int i= n-1;i>=0;i--)
for(int j=1;j<=n;j++){
if(n-i-j+1<=m)
dp[i][j] = dp[i][j-1]%MOD; //pop
if(i+1+j<=n)
dp[i][j] =(dp[i][j]%MOD+dp[i+1][j]%MOD);//push
}
cout<<dp[0][n]<<endl;
return 0;
}
这个dp里面 i代表还有多少个数要入栈,j代表已经从栈里面出来了多少个数,
循环里面的判断:
第一个是判断栈的容量是否能容纳一个push操作;
第二个判断是状态转移路径是否合法;
状态转移是:
能到到f(i,j)状态的有两个触发动作:push&pop
push之前的状态是: f(i+1,j)
pop之前的状态是: f(i,j-1)
所以最后答案是:f(0,n)