题目背景
栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表。
栈有两种最重要的操作,即 pop(从栈顶弹出一个元素)和 push(将一个元素进栈)。
栈的重要性不言自明,任何一门数据结构的课程都会介绍栈。宁宁同学在复习栈的基本概念时,想到了一个书上没有讲过的问题,而他自己无法给出答案,所以需要你的帮忙。
题目描述
宁宁考虑的是这样一个问题:一个操作数序列,1,2,…,𝑛1,2,…,n(图示为 1 到 3 的情况),栈 A 的深度大于 𝑛n。
现在可以进行两种操作,
- 将一个数,从操作数序列的头端移到栈的头端(对应数据结构栈的 push 操作)
- 将一个数,从栈的头端移到输出序列的尾端(对应数据结构栈的 pop 操作)
使用这两种操作,由一个操作数序列就可以得到一系列的输出序列,下图所示为由 1 2 3
生成序列 2 3 1
的过程。
(原始状态如上图所示)
你的程序将对给定的 𝑛n,计算并输出由操作数序列 1,2,…,𝑛1,2,…,n 经过操作可能得到的输出序列的总数。
输入格式
输入文件只含一个整数 𝑛n(1≤𝑛≤181≤n≤18)。
输出格式
输出文件只有一行,即可能输出序列的总数目。
输入输出样例
输入 #1复制
3
输出 #1复制
5
说明/提示
【题目来源】
NOIP 2003 普及组第三题
#include "bits/stdc++.h" using namespace std; const int N = 20; typedef long long ll; ll f[N][N]; //j 表示当前有多少数进站了,i表示当前有多少数出战了, f[i][j]表示当前情况下的出栈顺序 int main(){ int n; cin>>n; for(int i = 0; i <= n; i ++) f[0][i] = 1; for(int i = 1; i <= n; i ++){ for(int j = i; j <= n; j ++){ if(i == j) f[i][j] = f[i -1][j];//当出栈等于入栈的数量时,栈空,上一步一定要入栈 else f[i][j] = f[i -1][j] + f[i][j - 1];//当站不空时,可以是j个数入栈,但是出了i - 1个过来的,也可能是j- 1个数入栈,i个数出栈过来的,总结就是要么是出栈要么是入栈 } } cout<<f[n][n]; return 0; }
我自己用的dfs打表写的,这是看的大佬题解,但是感觉大佬题解有点没看懂,自己理解了一下,应该是没有问题的。
#include "bits/stdc++.h" using namespace std; stack<int> st, st1, st2; long long x; long long a[50]; long long summ = 0; void f(int in, int out){ // cout<<in<<" "<<out<<endl; if(in == x && out == x){ summ ++; // return ; } if(in < x){ st1.push(a[in]); f(in + 1, out); st1.pop(); } if(in > out && out < x){ st1.pop(); f(in , out + 1); st1.push(a[out]); } // cout<<" "<<st1.size()<<" "<<st2.size()<<"***"<<endl; } int main(){ // int x; std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); // cin>>x; for(int j = 1; j <= 18; j ++){ x = j; summ = 0; for(long long i = 1; i <= x; i ++){ a[i- 1] = i; } f(0, 0); cout<<summ<<endl; } return 0; }
#include "bits/stdc++.h" using namespace std; long long a[19]; int main(){ long long a[19] = {1,2,5,14,42,132,429,1430,4862,16796,58786,208012,742900,267440,9694845,35357670,129644790,477638700}; int x; cin>>x; cout<<a[x - 1]; return 0; }
#include "bits/stdc++.h" using namespace std; stack<int> st, st1, st2; long long x; long long a[50]; long long summ = 0; void f(int in, int out){ // cout<<in<<" "<<out<<endl; if(in == x && out == x){ summ ++; // return ; } if(in < x){ st1.push(st.top()); st.pop(); f(in + 1, out); st.push(st1.top()); st1.pop(); } if(in > out && out < x){ st.push(st1.top()); st1.pop(); f(in , out + 1); st1.push(st.top()); st.pop(); } // cout<<" "<<st1.size()<<" "<<st2.size()<<"***"<<endl; } int main(){ // int x; std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>x; summ = 0; for(long long i = 1; i <= x; i ++){ st.push(i); } f(0, 0); cout<<summ<<endl; return 0; }