浅谈“卡特兰数”
Posted -wallace-
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈“卡特兰数”相关的知识,希望对你有一定的参考价值。
引入:卡特兰数。
卡特兰数又称卡塔兰数,英文名Catalan number,是组合数学中一个常出现在各种计数问题中出现的数列。
——百度百科
一:运算公式。
令h(0)=1,h(1)=1,catalan数满足递推式 :
h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)*h(0) (n>=2)
例如:
h(3)=h(0)*h(2)+h(1)*h(1)+h(2)*h(0)=1*2+1*1+2*1=5
二:代码实现。
#include <bits/stdc++.h> int n, f[30]; int main() { scanf("%d",&n); f[0]=1,f[1]=1; for(int i=2; i<=n; i++) for(int j=0; j<i; j++) f[i]+=f[j]*f[i-j-1]; //卡特兰数 printf("%d",f[n]); return 0; }
这里用了递推的算法。
还可以用递归实现:
#include<bits/stdc++.h> using namespace std; int h(int n)
{ if(n==0||n==1) return 1; return h(n-1)*(4*n-2)/(n+1);//公式 } int main(){ int n; cin>>n; cout<<h(n); return 0; }
三:应用。
·题目描述
Luogu P1044 栈 [原题链接]
·解析
本题的描述十分简单。n个数依次进栈,可随机出栈。求有几种可能。
DFS是可以解的,但仔细思考思考,就会发现一个更简单的方法。
我们不妨建立数组f。f[i]表示i个数进出的全部可能性。
那么f[0] = 1, f[1] = 1;(0个数或1个数也没什么其他可能了。)
若设 x 为当前出栈序列的最后一个,则x有n种取值
由于x是最后一个出栈的,所以可以将已经出栈的数分成两部分
- 比x小
- 比x大
比x小的数有x-1个,所以这些数的全部出栈可能为f[x-1]
比x大的数有n-x个,所以这些数的全部出栈可能为f[n-x]
这两部分互相影响,所以一个x的取值能够得到的所有可能性为f[x-1] * f[n-x]
另外,由于x有n个取值,所以:
ans = f[0]*f[n-1] + f[1]*f[n-2] + ... + f[n-1]*f[0];
显而易见——卡特兰数!
题目的数据范围很小,所以直接贴模板也是可以过的。
四:总结。
那么,就先这样吧。其实Catalan数还有以下用法:
- 括号化 矩阵连乘: P=a1×a2×a3×……×an,依据乘法结合律,不改变其顺序,只用括号表示成对的乘积,试问有几种括号化的方案?(h(n)种)
- 给定节点组成二叉搜索树:给定N个节点,能构成多少种不同的二叉搜索树?(能构成h(N)个)(这个公式的下标是从h(0)=1开始的)
n对括号正确匹配数目:给定n对括号,求括号正确配对的字符串数。(h(n)种)
·经典必练
P1722 矩阵 II [原题链接]
以上是关于浅谈“卡特兰数”的主要内容,如果未能解决你的问题,请参考以下文章