当前位置:   article > 正文

C++卡特兰数_卡特兰数c++最省时间的算法

卡特兰数c++最省时间的算法

卡特兰数简介

卡特兰数又称卡塔兰数,卡特兰数是组合数学中一个常出现在各种计数问题中的数列。以比利时的数学家欧仁·查理·卡塔兰 (1814–1894)的名字来命名。但最早是欧拉在1753年解决凸包划分成三角形问题的时候,推出的Catalan数。

初始值:f(0) = f(1) = 1
递推公式:f(n) = f(0) * f(n - 1) + f(1) * f(n - 2) + …… + f(n - 1) * f(0)

解决的问题:

  1. 括号化:P=a1×a2×a3×……×an,依据乘法结合律,不改变其顺序,只用括号表示成对的乘积,试问有几种括号化的方案?(答案:catalan[n])
  2. 出栈次序:一个栈的进栈序列为1,2,3,…,n,有多少个不同的出栈序列?(答案:catalan[n])
  3. 凸多边形三角划分:在一个凸多边形中,通过若干条互不相交的对角线,把这个多边形划分成了若干个三角形,共有多少种不同的分法?(答案:catalan[n - 2])
  4. 给定节点组成二叉搜索树:给定N个节点,能构成多少种不同的二叉搜索树?(答案:catalan[n])
  5. n对括号正确匹配数目:给定n对括号,括号正确配对的字符串数是多少?(答案:catalan[n])

这里我以第二个出栈次序的问题来讲述卡特兰数的由来。首先,我们设f(n)表示序列个数为n的出栈序列种数。(我们假定,最后出栈的元素为k,显然,k取不同值时的情况是相互独立的,也就是求出每种k最后出栈的情况数后可用加法原则,由于k最后出栈,因此,在k入栈之前,比k小的值均出栈,此处情况有f(k-1)种,而之后比k大的值入栈,且都在k之前出栈,因此有f(n-k)种方式,由于比k小和比k大的值入栈出栈情况是相互独立的,此处可用乘法原则,共f(n-k)*f(k-1)种,而k可以取1 ~ n,将所有的f(n-k)*f(k-1)求和便是Catalan递推式。

卡特兰数代码

有了递推关系式,代码简单到爆。

(PS:NR是指catalan数组元素个数的上限)

# include <cstdio>
# include <iostream>
# include <cmath>
# include <cstring>
# include <algorithm>
# include <climits>

using namespace std;

# define FOR(i, a, b) for(int i = a; i <= b; i++)
# define _FOR(i, a, b) for(int i = a; i >= b; i--)

const int NR = 100000;

int n;
long long catalan[NR + 10];

int main()
{
	scanf("%d", &n);
	catalan[0] = catalan[1] = 1;
	FOR(i, 2, n)
		FOR(j, 0, i - 1)
			catalan[i] += catalan[j] * catalan[i - j - 1];
	printf("%lld\n", catalan[n]);
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

God Bless You For Ever!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/76142
推荐阅读
相关标签
  

闽ICP备14008679号