卡特兰数

卡特兰数

  • 定义
    卡特兰数非常常见,最为典型的就是给定n个1和n个0排列成为一个2n长度的01序列,要求对于任一个1k2n都有从第一个数到第k个数中0的个数都不少于1的个数。
  • 求法及其推导
    我们可以把这个01序列抽象成一个具体的问题:
    0代表向右走一步,1代表向上走一步,要求一共向右走n步向上走n步对于任一时刻向右走的步数都大于向上走的步数,最终到达(n,n)。
    我们不难发现y=x是一个分界点,如果走的路线全部都在y=x(图中绿线)的下方或者只是碰到y=x并未越过它则符合条件,当且仅当路线与y=x+1(图中红线)有交点不符合条件。
    输入图片说明
    设不符合条件的路径与红线的第一个交点为t,
    输入图片说明
    这里有一系列逻辑推导关系:线ttt沿线(n1,n+1),因为到达(n-1,n+1)点一定会穿过红线那么就有:所有非法路径的条数等于到(n-1,n+1)的条数。即为:C2nnC2nn1=(2n)!n!n!(2n)!(n1)!(n+1)=(2n)!(n+1)(n+1)!n!(2n)!nn!(n+1)!=2n!(n+1)!n!=1n+12n!n!n!=1n+1C2nn,所以卡特兰数为:C2nnn+1
    -代码实现
    给定n个0和n个1,求卡特兰数,结果模上109+7
#include<iostream>

using namespace std;
typedef long long  LL;
const int N=2e5+10;
const int mod=1e9+7;
int fact[N],infact[N];
int qmi(int a,int b,int p)
{
    int res=1;
    while(b)
    {
        if(b&1)
        {
            res=(LL)res*a%p;
        }
        b>>=1;
        a=(LL)a*a%p;
    }
    return res;
}
int main()
{
    int n;
    cin>>n;
    int a=2*n,b=n;
    fact[0]=infact[0]=1;
    for(int i=1;i<=a;i++)
    {
        fact[i]=(LL)fact[i-1]*i%mod;
        infact[i]=(LL)infact[i-1]*qmi(i,mod-2,mod)%mod;
    }
    int res=(LL)fact[a]*infact[b]%mod*infact[b]%mod*qmi(n+1,mod-2,mod)%mod;
    printf("%d",res);
    return 0;
}
posted @   Taco_gu  阅读(127)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示