卡特兰数(Catalan)

性质公式

太神奇辣,卡特兰数

1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862…

先放三种推导方法如下

递归推导

公式1

C n = ∑ k = 0 n − 1 C k C n − 1 − k = C 0 C n − 1 + C 1 C n − 2 + . . . + C n − 1 C 0 C_{n}=\sum_{k=0}^{n-1} C_{k} C_{n-1-k}=C_0C_{n-1} + C_1C_{n-2} +...+C_{n-1}C_0 Cn=k=0n1CkCn1k=C0Cn1+C1Cn2+...+Cn1C0

(n>=2)

递推公式

公式2

C n = 4 n − 2 n + 1 C n − 1 C_n = \frac{4n-2}{n+1}C_{n-1} Cn=n+14n2Cn1

通项公式

公式3

C n = 1 n + 1 C 2 n n C_n = \frac{1}{n+1}C^{n}_{2n} Cn=n+11C2nn

公式4

C n = C 2 n n − C 2 n n − 1 C_n = C_{2n} ^{n}- C_{2n}^{n-1} Cn=C2nnC2nn1

C n = 1 n + 1 ∑ i = 0 n ( C n i ) 2 C_n = \frac{1}{n+1}\sum_{i=0}^{n}(C^{i}_{n})^2 Cn=n+11i=0n(Cni)2

如果这个数太大,那么题目可能会要求取模,那么第1种𝑛太大的时候时空太大;第2种在取模运算中万一不小心整除了就凉了;第3种是除法运算,更行不通;唯有第4种,满足取模原则(加减无所谓),且不会出现倍数出错的情况,所以第4种解为最优解;

/数论做法 卡特兰数
//公式1:
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
ll f[20];
int main(){
    int n;
	f[0]=f[1]=1;
	cin>>n;
	for(int i=2;i<=n;i++)
	{
		for(int j=0;j<i;j++)
		{
			f[i] += f[j]*f[i-j-1];
		}
	}
	cout<<f[n];
	return 0;
}

//公式2:
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
ll f[20];
int main(){
    int n;
	f[0]=f[1]=1;
	cin>>n;
	for(int i=2;i<=n;i++)
	{
		f[i] = f[i-1]*(4*i-2)/(i+1);
	}
	cout<<f[n];
	return 0;
}

//公式3:
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
ll c[50][25];
int main(){
	int n;
    cin>>n;
    scanf("%d",&n);
    for(int i = 1; i <= 2*n; i++){
        c[i][0] = c[i][i] = 1;
        for(int j = 1; j < i; j++){
            c[i][j] = c[i-1][j] + c[i-1][j-1];
        }
    }
    cout<<c[2*n][n]/(n+1);
    return 0;
}

//公式4: 
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
ll c[50][25];
int main(){
	int n;
    cin>>n;
    for(int i = 1; i <= 2*n; i++){
        c[i][0] = c[i][i] = 1;
        for(int j = 1; j < i; j++){
            c[i][j] = c[i-1][j] + c[i-1][j-1];
        }
    }
    cout<<c[2*n][n] - c[2*n][n-1];
    return 0;
}

常见题目

常见的特点是:一种操作不能超过另一种,两种操作不能有交集,求这些方案合法数

括号匹配

和进出栈问题是一样的,以括号匹配为例

思路1

给n个(,n个),求有多少个2n长度的括号序列合法

无论对错总数量是 C 2 n n C^n_{2n} C2nn 即2n个里随便选n个

我们记错(为+1,)为-1

但是有一些错误匹配的情况我们需要排除掉,当错误刚出现,一定有一个特点,就是右括号目前多了一次,比如())()(,在遍历到第二个)就停止了,因为出错了

设映射f,f作用是翻转出错序列,每一个括号序列对应的f一定唯一。翻转后,有+1出现4次,-1出现2次的性质,即 C 2 n n − 1 C^{n-1}_{2n} C2nn1 即2n个里随便选n-1个

总次数就是 C 2 n n − C 2 n n − 1 C^n_{2n} - C^{n-1}_{2n} C2nnC2nn1符合卡特兰数通项定义

思路2

我们可以这样想,假设k是最后一个出栈的数。比k早进栈且早出栈的有k-1个数,一共有h(k-1)种方案。比k晚进栈且早出栈的有n-k个数,一共有h(n-k)种方案。所以一共有h(k-1) * h(n-k)种方案。显而易见,k取不同值时,产生的出栈序列是相互独立的,所以结果可以累加。k的取值范围为1至n,所以结果就为h(n)= h(0)h(n-1)+h(1)h(n-2) + … + h(n-1)h(0)。

二叉树组成

给n个节点,问能组成多少种不同二叉树。

我们可以假设,如果采用中序遍历的话,根结点第k个被访问到,则根结点的左子树有k-1个点、根结点的右指数有n-k个点。k的取值范围为1到n。与上面思路2卡特兰数的递归推导一样

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值