C++卡特兰数

(2) 2024-05-05 13:23

Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说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;
}

God Bless You For Ever!

今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

上一篇

已是最后文章

下一篇

已是最新文章

发表回复