卡特兰数(catalan)总结
卡特兰数的公式
递推公式1:$f(n)=\sum \limits_{i=0}^{n-1}f(i)*f(n-i-1)$
递推公式2:$f(n)=\frac{f(n-1)*(4*n-2)}{n+1}$
组合公式1:$f(n)=\frac{C_{2n}^{n}}{n+1}$
组合公式2:$f(n)=C_{2n}^{n}-C_{2n}^{n-1}$
关于卡特兰数的题目
1. 有限制的网格方案数 eg网格
利用组合数的思想:
对于长N宽M的网格(下图2),方案数为 $C_{n+m}^{m}-C_{n+m}^{m-1}$
理解:走到(n,m)这个点总共要走n+m步,其中有m步一定是向上的,所以$C_{n+m}^{m}$这是所有情况
但有不合法的情况,且不合法的一定经过绿线,将原图形沿其翻折,相当于走到c点,此时总n+m步不变,但只有m-1步是向右的
所以$C_{n+m}^{m-1}$是不合法的
(借用kaola学长的图)
对于N×N的网格就是卡特兰数了,如图一
本题先将式子化简,然后将其分解质因数,消去除法,最后乘上每个质数的个数次方就好
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int n,m,num,p[],v[];
int sum[];
void prime(int x)
{
for(int i=;i<=x;i++)
{
if(!v[i]) {v[i]=i;p[++num]=i;}
for(int j=;j<=num;j++){
if(p[j]>v[i]||i*p[j]>x) continue;
v[i*p[j]]=p[j];
}
}
}
int len=,ans[];
void mul(int x)
{
int k=;
for(int i=;i<=len;i++)
{
ans[i]=ans[i]*x+k;
k=ans[i]/;
ans[i]%=;
if(k>&&i==len) len++;
}
}
int main()
{
ans[]=;
scanf("%d%d",&n,&m);
prime(n+m+);
int t=n+-m;
while(t>)
{
sum[v[t]]++;
t/=v[t];
}
for(int i=n+m;i>=n+;i--)
{
t=i;
while(t>)
{
sum[v[t]]++;
t/=v[t];
}
}
for(int i=;i<=m;i++)
{
t=i;
while(t>)
{
sum[v[t]]--;
t/=v[t];
}
}
for(int i=;i<=num;i++)
for(int j=;j<=sum[p[i]];j++)
mul(p[i]);
for(int i=len;i>=;i--)
printf("%d",ans[i]);
puts("");
}
2.有趣的数列
其实这个也可以理解为上一个网格,将偶数位记为向右走一步,奇数位记为向上走一步,,偶数位之和大于奇数位之和,就是不能越过绿线
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define ll long long
using namespace std;
const int maxn=;
int n,mod,num;
ll p[maxn];int v[maxn];
ll sum[maxn];
void prime(int x)
{
for(int i=;i<=x;i++)
{
if(!v[i]) {v[i]=i;p[++num]=i;}
for(int j=;j<=num;j++){
if(p[j]>v[i]||i*p[j]>x) break;
v[i*p[j]]=p[j];
}
}
}
ll qpow(int a,int b)
{
ll ans=;
while(b)
{
if(b&) ans=ans*a%mod;
a=a*a%mod;
b>>=;
}
return ans%mod;
}
int main()
{
scanf("%d%d",&n,&mod);
prime(*n+);
for(int i=*n;i>=n+;i--)
{
int t=i;
while(t>)
{
sum[v[t]]++;
t/=v[t];
}
}
for(int i=;i<=n;i++)
{
int t=i;
while(t>)
{
sum[v[t]]--;
t/=v[t];
}
}
ll ans=;
for(int i=;i<=num;i++)
if(sum[p[i]])
ans=ans*qpow(p[i],sum[p[i]])%mod;
printf("%lld\n",ans);
}
3.树屋阶梯
我们不妨手模样例,若扣去左下角直角所在矩形,
图一和图四的方案数为右面的2块的方案数×上面的0块的方案数,即为$f(3)+=f(2)*f(0)$
同理图二和图五为$f(3)+=f(0)*f(2)$ 图三为$f(3)+=f(1)*f(1)$
由此可得 $f(n)=\sum \limits_{i=0}^{n-1}f(i)*f(n-i-1)$ 卡特兰数公式1
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int n,num,p[],v[];
int sum[];
void prime(int x)
{
for(int i=;i<=x;i++)
{
if(!v[i]) {v[i]=i;p[++num]=i;}
for(int j=;j<=num;j++){
if(p[j]>v[i]||i*p[j]>x) break;
v[i*p[j]]=p[j];
}
}
}
int len=,ans[];
void mul(int x)
{
int k=;
for(int i=;i<=len;i++)
{
ans[i]=ans[i]*x+k;
k=ans[i]/;
ans[i]%=;
if(k>&&i==len) len++;
}
}
int main()
{
ans[]=;
scanf("%d",&n);
prime(*n+);
for(int i=*n;i>=n+;i--)
{
int t=i;
while(t>)
{
sum[v[t]]++;
t/=v[t];
}
}
for(int i=;i<=n;i++)
{
int t=i;
while(t>)
{
sum[v[t]]--;
t/=v[t];
}
}
for(int i=;i<=num;i++)
for(int j=;j<=sum[p[i]];j++)
mul(p[i]);
for(int i=len;i>=;i--)
printf("%d",ans[i]);
puts("");
}
关于卡特兰数的其他应用
1.出栈入栈问题:1,2,~n个数经过一个栈,合法的出栈序列$Cat(n)$
(引用学长的课件)出栈次序是卡特兰数的一个应用。 我们将入栈视为+1,出栈视为-1,则限制条件为在任意位置前缀和不小于0 。 我们讨论这个问题与卡特兰数有什么关系。 为了方便,我们按入栈的先后顺序将各个元素由1到n编号。 假设最后一个出栈的数为k。 则在k入栈之前,比k小的数一定全部出栈,所以这部分方案数为h(k-1)。 在k入栈之后,比k大的数在k入栈之后入栈,在k出栈之前出栈,所以这部分的方案数为h(n-k)。 这两部分互不干扰,则方案数为h(k-1)*h(n-k) 枚举k,得到的公式就是卡特兰数的递推公式。
2.左括号与右括号的匹配问题:n个左括号和n个右括号组成的合法括号序列$Cat(n)$
跟入栈出栈的理解是一样的
3.n个节点构成的二叉树的方案数为$Cat(n)$
假设左子树有$i$个节点,右子树有$n-i-1$个节点,i从0到n-1,根据乘法原理
可得公式1$f(n)=\sum \limits_{i=0}^{n-1}f(i)*f(n-i-1)$
卡特兰数(catalan)总结的更多相关文章
- 卡特兰数 Catalan数 ( ACM 数论 组合 )
卡特兰数 Catalan数 ( ACM 数论 组合 ) Posted on 2010-08-07 21:51 MiYu 阅读(13170) 评论(1) 编辑 收藏 引用 所属分类: ACM ( 数论 ...
- 浅谈卡特兰数(Catalan number)的原理和相关应用
一.卡特兰数(Catalan number) 1.定义 组合数学中一个常出现在各种计数问题中出现的数列(用c表示).以比利时的数学家欧仁·查理·卡特兰的名字来命名: 2.计算公式 (1)递推公式 c[ ...
- 卡特兰数 catalan number
作者:阿凡卢 出处:http://www.cnblogs.com/luxiaoxun/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留 ...
- 卡特兰数(Catalan Number) 算法、数论 组合~
Catalan number,卡特兰数又称卡塔兰数,是组合数学中一个常出现在各种计数问题中出现的数列.以比利时的数学家欧仁·查理·卡塔兰 (1814–1894)命名. 卡特兰数的前几个数 前20项为( ...
- 卡特兰数 Catalan 笔记
一.公式 卡特兰数一般公式 令h(0)=1,h(1)=1,catalan数满足递推式.h(n) = h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n>= ...
- 卡特兰数(Catalan)及其应用
卡特兰数 大佬博客https://blog.csdn.net/doc_sgl/article/details/8880468 卡特兰数是组合数学中一个常出现在各种计数问题中出现的数列. 卡特兰数前几项 ...
- ACM数论-卡特兰数Catalan
Catalan 原理: 令h(0)=1,h(1)=1,catalan 数满足递归式: (其中n>=2) 另类递推公式: 该递推关系的解为: (n=1,2,3,...) 卡特兰数的应用实质上都是递 ...
- 卡特兰数(Catalan Number) 学习笔记
一.三个简单的问题 1.给定一串长为2n的01序列,其中0和1的数量相等,满足任意前缀中0的个数不少于1的个数,求序列的个数 2.给出一串长为n的序列,按顺序将他们进栈,随意出栈,求最后进出栈的方案 ...
- 【知识总结】卡特兰数 (Catalan Number) 公式的推导
卡特兰数的英文维基讲得非常全面,强烈建议阅读! Catalan number - Wikipedia (本文中图片也来源于这个页面) 由于本人太菜,这里只选取其中两个公式进行总结. (似乎就是这两个比 ...
- 【2020.12.01提高组模拟】卡特兰数(catalan)
题目 题目描述 今天,接触信息学不久的小\(A\)刚刚学习了卡特兰数. 卡特兰数的一个经典定义是,将\(n\)个数依次入栈,合法的出栈序列个数. 小\(A\)觉得这样的情况太平凡了.于是,他给出了\( ...
随机推荐
- 通过数据库中的表,使用 MyEclipse2017的反向生成工具-->hibernate反转引擎引擎(MyEclipse2017自带的插件) 来反转生成实体类和对应的映射文件
通过数据库中的表,使用 MyEclipse2017的反向生成工具-->hibernate反转引擎引擎(MyEclipse2017自带的插件) 来反转生成实体类和对应的映射文件 文章目录 Ja ...
- JPA 中注解的作用
JPA全称Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中. JPA由EJB 3.0软件专家 ...
- day 45 前端CSS
前端CSS CSS介绍 CSS(Cascading Style Sheet,层叠样式表)定义如何显示HTML元素,给HTML设置样式,让它更加美观. 当浏览器读到一个样式表,它就会按照这个样式 ...
- Java 使用JDBC连接MySQL
// 这学期本来不打算深入学习Java的,课上的小项目也就随便写了一个简单计算器和扫雷游戏就糊弄过去.可是我们的Eliza老师偏偏什么都讲了,考虑到期末也会涉及到JDBC的内容,前些天试着学习一番. ...
- 07_Spring事务处理
一.事务概述 数据库的事务: 事务是一组操作的执行单元,相对于数据库操作来讲,事务管理的是一组SQL指令,比如增加,修改,删除等.事务的一致性,要求,这个事务内的操作必须全部执行成功,如果在此过程种出 ...
- Python - 基本数据类型及其常用的方法之数字与字符串
数字(int): 1.int()(将字符串换为数字) a = " print(type(a), a) b = int(a) print(type(b), b) num = "a&q ...
- maven 项目在 tomcat 中启动报错:Caused by: java.util.zip.ZipException: invalid LOC header (bad signature)
问题原因: 在下载 maven 依赖包的时候出现某种原因导致下载的依赖包出现损坏,jvm 和 maven 不能正常识别,从而导致出现该问题. 解决办法: 在 maven 仓库中搜索: in-progr ...
- 在xml中对one2many 字段屏蔽 添加项目
在xml中对one2many 字段(mrp_workorder_variation_line_ids) 设置 只有在草稿状态下才能编辑 <field name="mrp_workord ...
- 移动端Web适配单位rem的坑,oppo r9手机出现错位bug
我们做了一个抽奖的H5活动页面,被一个oppo R9手机客户反馈,抽奖的转盘错位了.刷新了好几次都不行.网上百度一搜真的有部分安卓手机有坑.赶紧修复bug.分享完整的rem.js代码出来.各位看官自己 ...
- python基础---内置函数 和 匿名函数 知识点自查填空题
1.file ---默认是输出到(),如果设置为(),输出到() 2.sep---打印(),默认为() 3.end---每一次打印的结尾,默认为() 4.flush---立即把内容输出到(),不做() ...