算法中的数学—卡特兰数(解析+代码实现)

算法中的数学—卡特兰数(解析+代码实现)总结一下碰到的关于卡特兰数的问题,方便后续复习。

大家好,又见面了,我是你们的朋友全栈君。

  卡特兰数又称卡塔兰数,是组合数学中一种常出现于各种计数问题中的数列。

一、简单介绍

  卡特兰数是一个数列,其前几项为(从第零项开始) : 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420, 24466267020, 91482563640, 343059613650, 1289904147324, 4861946401452, …
卡特兰数满足如下递推关系:
在这里插入图片描述
其中 C n C_{n} Cn表示数列的第n项。根据上述第一个式子我们可以推出:
在这里插入图片描述
第二个推导式用于编程实现卡特兰数。

二、应用

2.1进出栈问题

【问题描述】
  1, 2, 3, 4依次进栈,则可能的一种进出栈顺序为:
1in->2in->2out->3in->4in->4out->3out->1out,所以出栈顺序为:2431,那么请问按照1, 2, 3, 4,…, n依次进栈,出栈顺序种数h(n)为多少?
【问题分析】
  对n个数,假设数k最后一个出栈,k有n种可能,即每一个数都有可能最后出栈,我们算出每一种可能各有多少种情况,最后相加即可。
  因为k最后一个出栈,而进栈顺序又是从小到大来的,所以k前面的k-1个数在k进栈以前就已经全部出栈了,我们把前面k-1个数看出一个整体,那么全面k-1个数的出栈情况实际上就有h(k-1)种。
  在k进栈之后,比k大的n-k个数才能进栈,但是它们又比k早出栈,把这n-k个数同样看成一个整体,共有h(n-k)种可能。 二者综合一下,当数k最后出栈时,一共有h(k-1)h(n-k)种可能,k从1取到n,再把每种可能相加即得到最终答案:
在这里插入图片描述
  简而言之就是数k把这段序列分成了两部分:比k大的部分和比k小的部分。因为中间有k隔着,而它们又必须按照从小到大的次序进栈,所以这两部分进出栈是相互不影响的。
  很明显可以看出,该表达式就是卡特兰数的递推式。

2.2排队方式

【问题描述】
  n个人手拿5元,n个人手拿10元,他们去排队买东西,东西价值5元,老板没有零钱(老板必须用收取的5元钞票给支付10元的顾客找零钱),请问一共有多少种排队方式?
【问题分析】
  将持5元者到达视作将5元入栈,持10元者到达视作使栈中某5元出栈, 实际上也就转换成了进出栈问题,答案也为h(n)。

2.3二叉树生成问题

【问题描述】
  有n个结点,请问总共能构成多少种不同的二叉树?
【问题分析】
  假设采用中序遍历,根节点第k个被访问,则根的左子树共有k-1个结点,右子树共有n-k个结点,k同样可以取1-n,这就与进出栈问题分析思路一致了,所以一共h(n)种。

2.4凸多边形三角形划分

【问题描述】
  一个凸的n边形,用直线连接它的两个顶点使之分成多个三角形,每条直线不能相交,问一共多少种方案?
比如凸六边形的划分情况为:
在这里插入图片描述
h(6)=14。
【问题分析】
  我们将凸多边形顶点从p1一直编号到pn,以p1pn这条边为基准,任选一个数k(2<=k<=n-1),将p1,pk以及pn三点连接,构成了一个三角形。该三角形把该凸边形划分成了两个凸边形,一边顶点为1 ~ k-1,另一边为k+1 ~ n,于是又回到了进出栈问题,所以答案依旧为:h(n)。

2.5括号匹配问题

【问题描述】
由1对括号,可以组成一种合法括号序列:()。
由2对括号,可以组成两种合法括号序列:()()、(())。
由n对括号组成的合法括号序列一共有多少种?
【问题分析】
  考虑n对括号时的任意一种配对方案,最后一个右括号有唯一的与之匹配的左括号,于是有唯一的表示A(B),其中A和B也是合法的括号匹配序列。
  假设S(n)为n对括号的正确配对数目,那么有递推关系S(n)=S(0)S(n-1)+S(1)S(n-2) +…+S(n-1)S(0),显然S(n)是卡特兰数。

2.6满二叉树个数

【问题描述】
  n+1个叶子的满二叉树个数为多少?
【问题分析】
  不再分析,答案为h(n)。

2.7圆划分问题

【问题描述】
  在圆上选2n个点,讲这些点成对连接起来,保证所有直线不相交,问一共多少种可能?
【问题分析】
  答案为h(n)。

2.8填充问题

【问题描述】
  n个长方形填充一个高度为n的阶梯状图像方法数为多少?
【问题分析】
  答案为h(n)。

代码实现:

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int maxn = 20;
int n;
ll f1[maxn], f2[maxn];
ll f[maxn * 2][maxn];
//公式1:
int solve1() { 

f1[0] = f1[1] = 1;
cin >> n;
for(int i = 2; i <= n; i++) { 

for(int j = 0; j < i; j++) { 

f1[i] += (f1[j] * f1[i-j-1]);   //f(n)=f(0)f(n-1)+f(1)f(n-2)+...+f(n-1)f(0) 
}
}
printf("%lld\n",f1[n]);
return 0;
}
//公式2:
int solve2() { 

f2[0] = f2[1] = 1;
cin >> n;
for(int i = 2; i <= n; i++)
{ 

f2[i] += f2[i - 1] * (4 * i - 2) / (i + 1);  //f(n)=f(n-1)*(4*n-2)/(n+1)
}
printf("%lld\n", f2[n]);
return 0;
}
//公式3:
int solve3() { 

cin >> n;
for(int i = 1; i <= 2 * n; i++) { 

f[i][0] = f[i][i] = 1;
for(int j = 1; j < i; j++) { 

f[i][j] = f[i - 1][j] + f[i - 1][j - 1];     //f(n)=c(2n,n)/(n+1)
}
}
printf("%lld",f[2 * n][n] / (n + 1));
return 0;
}
int main() { 

solve1();
solve2();
solve3();
return 0;
} 

  欢迎大家关注我的微信公众号:KI的算法杂记,有什么问题可以直接发私信。

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/132277.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • springBoot跨域注解@CrossOrigin

    springBoot跨域注解@CrossOriginSpringFramework4.2GA为CORS提供了第一类支持,使您比通常的基于过滤器的解决方案更容易和更强大地配置它。所以springMVC的版本要在4.2或以上版本才支持@CrossOrigin;springBoot跨域注解:@CrossOrigin在controller控制类上方加注解;spring注解@CrossOrigin不起作用的原因1、是s…

  • PyCharm激活码永久有效PyCharm2017.3.6激活码教程-持续更新,一步到位

    PyCharm激活码永久有效PyCharm2017.3.6激活码教程-持续更新,一步到位PyCharm激活码永久有效2017.3.6激活码教程-Windows版永久激活-持续更新,Idea激活码2017.3.6成功激活

  • SpringBoot启动流程–总结

    SpringBoot启动流程–总结说明:我这里只说结果,和简单的代码,面试应该是够了,毕竟源码内容不是所有人都能记住的,如果要学习源码请看其他大佬的文章,写的比较详细,而且差不多都一样。背景:面试经常会问道springboot启动流程或者原理,看了多数博友的文章,都是大同小异,但是面试的时候不可能那么多,所以我将启动流程总结一下。启动流程:1.启动springboot这需要执行SpringApplication执行类即可2.执行的时候执行两个重要的代码,@springBootAppli…

  • iocomp-Crack|New Version最新【2021】「建议收藏」

    iocomp-Crack|New Version最新【2021】「建议收藏」使用IocompComponents5.0以上能够助程序员开发出逼真的工控仪表和工控图表,让程序开发不再消耗时间和精力,有了这个控件不仅能节约开发时间,而且还降低了项目风险,最重要的是第三方控件写的程序更专业,工控图表图像更精细。他们用于生成具有专家级外观的仪器控件,并能紧密整合到Microsoft’s.NETFramework之中。您无需辛苦的在属性窗口中寻找该属性,其自定义的属性编辑器提供了简单快速的属性配置方法。Ultra控件包提供了70种专家级控件以及绘图控件包组件非常强大的

  • resultset类所有方法_resultset获取列名,和对应值

    resultset类所有方法_resultset获取列名,和对应值 chenjieuniqueResult()返回唯一结果(这种一般只会返一条实体类对象信息)Result()返回结果(展示所有结果)   publicTQuaAcceptancegetTQuaAcceptance(StringqaId){       //sql语句      Stringhql="fromTQuaAcceptance…

  • mysql中字符串转数字「建议收藏」

    mysql中字符串转数字「建议收藏」mysql中字符串在进行计算或排序的时候转数字比如以字符串111为例,方法一:SELECTCAST(‘111’ASSIGNED);方法二:SELECTCONVERT(‘111’,SIGNED);或者SELECTCONVERT(‘111’,decimal(10,5));方法三:SELECT‘111’+0;…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号