出栈序列总数问题与卡特兰数

题目及样例描述

洛谷题目链接:P1044
对于n个不同的元素进栈,将出栈顺序记录为一组元素序列,请问总共会有多少种不同的出栈顺序的元素序列?
例如:
输入 :3 \quad 输出 :5
样例解释:
比如输入序列:123(先输入1,然后是2和3)
可能的出栈顺序为:321,132,123,213,231一共5种

思路

利用递推(递归),类似数学归纳法的思路,假设 i i i个元素一共有 a [ i ] a[i] a[i]种出栈方式。考虑到入栈有顺序,而出栈实际上没有顺序,也就是说,每一个元素都可以最后一个出栈。我们现在让第 k k k个元素最后出栈。那么对于这个第 k k k个元素来说,有如下图示:
在这里插入图片描述对于前 k − 1 k-1 k1个元素,共有 a [ k − 1 ] a[k-1] a[k1]种出栈方式,对于后 n − k n-k nk个元素共有 a [ n − k ] a[n-k] a[nk]种出栈方式。前 k − 1 k-1 k1个元素出栈和后 n − k n-k nk个元素出栈没有顺序关系,所以对于元素 k k k,共有 a [ k − 1 ] ∗ a [ n − k ] a[k-1]*a[n-k] a[k1]a[nk]种出栈方式。
现在考虑 k k k有多少种可能。如果我们认为数组从1开始存储。那么, k k k就可以从1取到n,而 a [ n ] a[n] a[n]即为我们所希望求得的数。所以有:
a [ n ] = ∑ k = 1 n a [ k − 1 ] ∗ a [ n − k ] a[n] = \sum_{k=1}^{n}a[k-1]*a[n-k] a[n]=k=1na[k1]a[nk]
显然, a [ 1 ] = 1 a[1]=1 a[1]=1。因为长度为1的序列只有一种出栈可能。为了数学形式保持一致,我们规定 a [ 0 ] = 1 a[0]=1 a[0]=1,这样递推式就对 a [ 2 ] = a [ 0 ] ∗ a [ 1 ] + a [ 1 ] ∗ a [ 0 ] a[2]=a[0]*a[1]+a[1]*a[0] a[2]=a[0]a[1]+a[1]a[0]也成立。

代码及代码解释

#include<bits/stdc++.h>
using namespace std;
int a[20];
int main(){
	int n;
	cin>>n;
	a[0]=a[1]=1; 
	for(int i = 2;i<=n;i++){
		for(int j = 1;j<=i;j++){
			a[i] += a[j-1]*a[i-j];
		}
	}
	cout<<a[n];
	return 0;
} 

解释:
a [ n ] = ∑ k = 1 n a [ k − 1 ] ∗ a [ n − k ] a[n] = \sum_{k=1}^{n}a[k-1]*a[n-k] a[n]=k=1na[k1]a[nk]
展开可以写成;

for(...j=1->i)
a[i] = a[i] + a[j-1]*a[i-j];
等价于:
for(...j=1->i)
a[i] += a[k-1]*a[i-k];

而上面的 i i i又可以从2取到 n n n i = 0 , i = 1 i=0,i=1 i=0,i=1的情况已经指定为1),所以外层再加一个循环。

for(int i = 2;i<=n;i++){
	//上面的代码
}

数学联系-卡特兰数

卡特兰数简介
卡特兰数是组合数学中一个常出现于各种计数问题中的数列。其前几项为(从第0项开始):1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900 … \dots
这里给出一种定义式(递推公式):
在这里插入图片描述
可以看到,这和我们的题目要求极其相似。
对这个序列,如果我们令
0->1则有:
1->1
2->2
3->5
4->14
… \dots
如果左边是输入,则右边就是程序相应的输出。
最后推荐一篇联推导卡特兰数递推式的文章
推导过程链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值