洛谷 P1976 鸡蛋饼 C++实现 科特兰数

原题地址:P1976 鸡蛋饼-洛谷

题目背景

Czyzoiers 都想知道小 x 为什么对鸡蛋饼情有独钟。经过一番逼问,小 x 道出了实情:因为他喜欢圆。

题目描述

最近小 x 又发现了一个关于圆的有趣的问题:在圆上有 2N 个不同的点,小 x 想用 N 条线段把这些点连接起来(每个点只能连一条线段), 使所有的线段都不相交,他想知道这样的连接方案有多少种?

输入输出格式

输入格式:

有且仅有一个正整数 N 。 (N <= 2999)

输出格式:

要求的方案数(结果 mod 100000007)。

输入输出样例

输入样例#1:
24
输出样例#1:
4057031

解题思路:

刚开始做这道题的时候,发现这和 洛谷 P1044 栈 C语言实现 从本质上来讲是一个意思啊,而且这个题还更明白一点。

首先一共有 2 N 2N 2N个点,要让每个点都仅和一个点向连,并且不能有空留的点。

所以可以把这个看成,第一对点相连后把这个圆分为左右两个部分,当左边还剩 a a a 对点的时候,右边还剩 N − a − 1 N - a - 1 Na1 对点,
这个情况下,有多少种组成方式就有 f ( a ) ∗ f ( N − a − 1 ) f(a) * f(N - a - 1) f(a)f(Na1) 种( f ( n ) f(n) f(n)表示有 2 ∗ n 2*n 2n 个点时,一共有多少种组成方案)。

而且很容易就可以推算出 f ( 0 ) = 1 , f ( 1 ) = 1 f(0) = 1, f(1) = 1 f(0)=1,f(1)=1.

然后左边剩下的 a a a 对点的取值范围时 0 到 N − 1 0 到 N - 1 0N1,于是乎:
a n s = f [ 0 ] ∗ f [ n − 1 ] + f [ 1 ] ∗ f [ n − 2 ] + . . . + f [ n − 1 ] ∗ f [ 0 ] ; ans=f[0]∗f[n−1]+f[1]∗f[n−2]+...+f[n−1]∗f[0]; ans=f[0]f[n1]+f[1]f[n2]+...+f[n1]f[0];
最后注意一下求模,不要让数据溢出就行了。

A C AC AC代码:

#include <iostream>
using namespace std;
int main(){
	long long int a[6000] = {1, 1};
	int n;
	cin >> n;
	for(int i = 2; i <= n; i ++)
		for(int j = 0; j < i; j++)
			a[i] = (a[j] * a[i - j - 1] % 100000007 + a[i]) % 100000007;
	cout << a[n];
	return 0;
} 

当发现这道题的本质和 洛谷 P1044 栈 C语言实现 很相识之后,我就再去查了一下,发现他们都是属于 卡 特 兰 数 卡特兰数

然后在了解的过程中发现了一篇不错的博客 卡特兰数 — 计数的映射方法的伟大胜利

简单来说就是:(摘之百度百科)

设 h ( n ) 为 c a t a l a n 数 的 第 n 项 , 令 h ( 0 ) = 1 , h ( 1 ) = 1 , c a t a l a n 数 满 足 递 推 式 : 设h(n)为catalan数的第n项,令h(0)=1,h(1)=1,catalan数满足递推式 : h(n)catalannh(0)=1,h(1)=1catalan:
h ( n ) = h ( 0 ) ∗ h ( n − 1 ) + h ( 1 ) ∗ h ( n − 2 ) + . . . + h ( n − 1 ) ∗ h ( 0 ) ( n &gt; = 2 ) h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)*h(0) (n&gt;=2) h(n)=h(0)h(n1)+h(1)h(n2)+...+h(n1)h(0)(n>=2)
例 如 例如
h ( 2 ) = h ( 0 ) ∗ h ( 1 ) + h ( 1 ) ∗ h ( 0 ) = 1 ∗ 1 + 1 ∗ 1 = 2 h(2)=h(0)*h(1)+h(1)*h(0)=1*1+1*1=2 h(2)=h(0)h(1)+h(1)h(0)=11+11=2
h ( 3 ) = h ( 0 ) ∗ h ( 2 ) + h ( 1 ) ∗ h ( 1 ) + h ( 2 ) ∗ h ( 0 ) = 1 ∗ 2 + 1 ∗ 1 + 2 ∗ 1 = 5 h(3)=h(0)*h(2)+h(1)*h(1)+h(2)*h(0)=1*2+1*1+2*1=5 h(3)=h(0)h(2)+h(1)h(1)+h(2)h(0)=12+11+21=5
另 类 递 推 式 : 另类递推式:
h ( n ) = h ( n − 1 ) ∗ ( 4 ∗ n − 2 ) / ( n + 1 ) ; h(n)=h(n-1)*(4*n-2)/(n+1); h(n)=h(n1)(4n2)/(n+1);
递 推 关 系 的 解 为 : 递推关系的解为:
h ( n ) = C ( 2 n , n ) / ( n + 1 ) ( n = 0 , 1 , 2 , . . . ) h(n)=C(2n,n)/(n+1) (n=0,1,2,...) h(n)=C(2n,n)/(n+1)(n=0,1,2,...)
递 推 关 系 的 另 类 解 为 : 递推关系的另类解为:
h ( n ) = c ( 2 n , n ) − c ( 2 n , n − 1 ) ( n = 0 , 1 , 2 , . . . ) h(n)=c(2n,n)-c(2n,n-1)(n=0,1,2,...) h(n)=c(2n,n)c(2n,n1)(n=0,1,2,...)
以上就是本题的所有。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值