算法笔记练习 8.1 深度优先搜索(DFS) 问题 E: 【递归入门】出栈序列统计

算法笔记练习 题解合集

本题链接

题目

题目描述
栈是常用的一种数据结构,有n令元素在栈顶端一侧等待进栈,栈顶端另一侧是出栈序列。你已经知道栈的操作有两•种:push和pop,前者是将一个元素进栈,后者是将栈顶元素弹出。现在要使用这两种操作,由一个操作序列可以得到一系列的输出序列。请你编程求出对于给定的n,计算并输出由操作数序列1,2,…,n,经过一系列操作可能得到的输出序列总数。

输入
一个整数n(1<=n<=15)

输出
一个整数,即可能输出序列的总数目。

样例输入

3

样例输出

5

思路

DFS版本

void DFS(int wait, int stack);
DFS只需要两个形参来记录状态:

  • 目前等待入栈的元素数量wait
  • 目前栈内元素数量stack

递归边界:
waitstack同时等于 0 的时候,已经产生了一个合法输出,记录并返回。

递归调用:

  • 若还有正在等待的元素(wait > 0),可以令其入栈;
  • 若栈非空(stack > 0),可以令其出栈。

卡特兰数版本

其实读完题第一个想到的思路是直接算卡特兰数。若有 n n n 个元素等待入栈,合法的出栈序列数量就是卡特兰数:
1 n + 1 C 2 n n \frac1{n+1}C_{2n}^n n+11C2nn
如何计算组合数 C 2 n n C_{2n}^n C2nn 又是另一个话题了,可以参考算法笔记 5.8 组合数。

代码

DFS版本

#include <iostream>
using namespace std;
int ans = 0;
void DFS(int wait, int stack) {
	if (wait == 0 && stack == 0) {
		++ans;
		return;
	}
	if (wait > 0)
		DFS(wait - 1, stack + 1);
	if (stack > 0)
		DFS(wait, stack - 1); 
} 
int main() {
	int n, stack;
	while (scanf("%d", &n) != EOF) {
		ans = 0;
		DFS(n, 0);
		printf("%d\n", ans); 
	} 
	return 0;
}

卡特兰数版本

#include <iostream>
using namespace std;
int main() {
	long long n;
	while (scanf("%ld", &n) != EOF) {
		long long ans = 1;
		for (long long i = 1; i <= n; ++i)
			ans = ans * (n + i) / i;
		printf("%ld\n", ans / (n + 1)); 
	} 
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值