【算法】出栈序列统计-统计N个元素进入栈容量为M的所有出栈序列数

这么说吧,网上的解释看着蛋疼,同一道题竟然每个页都是同一个答案?

看题: 求有容量限制的栈的出栈序列统计

 

 

题目描述

  栈是常用的一种数据结构,它有两种操作:将一个元素进栈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) 
 

 

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值