这个题可以理解成是在一个有 n
个元素的栈和队列的情况下,能够以多少种方式输出所有的元素。
题目列表 - 洛谷 | 计算机科学教育新生态https://www.luogu.com.cn/problem/list?keyword=P1044%20%5BNOIP2003%20%E6%99%AE%E5%8F%8A%E7%BB%84%5D%20%E6%A0%88&type=AT%7CB%7CCF%7CP%7CSP%7CUVA&page=1
这里我们用动态规划来解决 ,什么是动态规划呢,我们先来看一个递归。
我们来看题:
我们把dp[i][j] 看作 栈里有i个元素,队列里有j个元素时 输出序列情况
栈里有i个元素,队列里有j个元素时:下一步有几种做法?
做法1:栈里面出去一个 dp[i-1][j];
做法2:栈里面进来一个 dp[i+1][j-1];
两种做法加起来 :则 dp[i][j]= dp[i-1][j]+ dp[i+1][j-1]; 这就是递推公式
如图假设 n=5; 取值0-5 ,大小为6;最终返回值是绿色,红色 是取不到的 因为元素总共就5个,
i+j <=5;红色为循环条件。然后我们要初始化 ,要把边界写出来。
先看最左边全是1的那列 表示为for (int i = 0; i <= n; i++)
dp[i][0] = 1;//这段代码表示:如果队列中没有元素(也就是 j=0)
//,那么无论栈中有多少个元素,只有一种方式,即直接将剩下的元素全部输出。
再看最上面一行 dp[0][j];栈里没元素,全在队列;所以只有出元素 dp[0][j] =dp[1][j-1];
我们从一列一列算其余位置
最终的答案为 dp[0][n]
,表示在栈中没有元素时,队列中的 n
个元素的输出方式数量。
下面给出每个位置情况
整个 DP 的逻辑可以总结为以下步骤:
- 初始化边界条件。
- 根据状态转移方程依次计算所有可能的
dp[i][j]
。 - 最终的答案为
dp[0][n]
,表示在栈中没有元素时,队列中的n
个元素的输出方式数量。