洛谷P1044栈
宁宁考虑的是这样一个问题:一个操作数序列,1,2,\ldots ,n1,2,…,n(图示为 1 到 3 的情况),栈 A 的深度大于 nn。
现在可以进行两种操作,
- 将一个数,从操作数序列的头端移到栈的头端(对应数据结构栈的 push 操作)
- 将一个数,从栈的头端移到输出序列的尾端(对应数据结构栈的 pop 操作)
使用这两种操作,由一个操作数序列就可以得到一系列的输出序列,下图所示为由 1 2 3
生成序列 2 3 1
的过程。
输入格式
输入文件只含一个整数 n(1<=n<=18)
输出格式
输出文件只有一行,即可能输出序列的总数目。
输入输出样例
输入 #1复制
1 | 3 |
输出 #1复制
1 | 5 |
思路分析
根据题目分析,很明显是一个“特殊”的全排列的问题,但是我们不能用简单的递归来做。
用 i 代表待排数,j表示栈内数,
1 | int f[][] = new int[20][20] //该数组代表序列的数量 |
数据有四种情况:
- 第一种是待排数 i 中为0,则直接返回1,意思即增加一种排序
- 一种是如果栈内不为空,且待排数中没有数了,则j-1出栈。
- 一种情况就是同时入栈和同时出栈 即 i-1 和 j+1。
除此之外一种情况是若f数组中的数不为0 则应该直接返回该数 避免重复计算
实现代码如下:
1 | public class g23 { |
总结:DFS与动态规划思想
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.