卡特兰数(Catalan)


卡特兰数

卡特兰数是组合数学中一个常出现在各种计数问题中的数列。

数列前几项:1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862,16796…

递推公式h(n)=((4*n-2)/(n+1))*h(n-1);

一、推导

一般树的递归表示导致其生成函数的隐函数定义

                                G(z) = z/( 1-G(z) ) 

解G实数解得

                               G(z)=1/2*(1-(√1-4z))

由二项展开公式

                          (1+x)^a^=1+(a/1!)x+(a(a-1)/2!)x^2^+...

代入a=1/2,x=-4z,

                  G(z) =z+z^2^+2z ^3^+5z^4^+14z^5^+ 42z^6^+ 132z^7^+....

数 Cn=(2n)!/(n+1)!n!
生成函数C(z)=(1-(√1-4z))/2z 称为Catalan数
一般树的枚举问题可归结为计算Catalan数

二、例题

括号生成

数字 n(1<=n<=8) 代表生成括号的对数,请你算出所有可能的并且有效的括号组合的个数

例如:

输入:n = 3
满足的组合:“((()))”,“(()())”,“(())()”,“()(())”,“()()()”,输出:5

输入格式:
输入在一行中给出n

输出格式:
输出个数

输入样例:
在这里给出一组输入。例如:

3
输出样例:
在这里给出相应的输出。例如:

5
代码长度限制
16 KB
时间限制
1000 ms
内存限制
128 MB

bfs:

#include<iostream>
#include<queue>
using namespace std;
int cnt;//n<=8
  int main()
{
   int n,z,y;
 queue<int>q;//zuo
 queue<int>p;//you
 cin>>n;
    q.push(1);
    p.push(0);
while(!q.empty())
 {
     z=q.front();
     y=p.front();
     q.pop();
     p.pop();
     if(z+y+1==2*n){cnt++;continue;}
     if(z+1<=n){q.push(z+1);p.push(y);}
     if(y+1<=z){p.push(y+1);q.push(z);}
 }
     cout<<cnt;
}

catalan:

#include<stdio.h>
#include<string.h>
int ans[102][100];//高精度,一行一个数
void list()
{
	ans[0][0]=ans[1][0]=1;
	int i,j;
	for(i=2;i<102;i++)
	{
		int c=0;
		for(j=0;j<100;j++)
		{
			ans[i][j]=ans[i-1][j]*(4*i-2)+c;
			c=ans[i][j]/10;
			ans[i][j]%=10;
		}
		int z=0;
		for(j=99;j>=0;j--)
		{
			z=z*10+ans[i][j];
			ans[i][j]=z/(i+1);
			z%=(i+1);
		}
	}
}
int main(){
	int t;
    list();
	while(~scanf("%d",&t))
	{
		int i=99;
		if(t==-1)
			break;
		while(ans[t][i]==0)
			i--;
		for(;i>=0;i--)
			printf("%d",ans[t][i]); 
		
		printf("\n");
	}
	return 0;
}

n对括号生成,凸n+2边形三角剖分,n个元素进出栈序列等可看成构造有n+1个叶子节点的满二叉树的计数问题,均符合卡特兰数的递归定义。


三、几何意义

https://blog.csdn.net/chenlong_cxy/article/details/113613203

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值