组合数_卡特兰定理

当求前缀排列问题时,可以尝试将纯数学的逻辑转换为几何的逻辑。
例:
给定 n 个 0 和 n 个 1,它们将按照某种顺序排成长度为 2n 的序列,求它们能排列成的所有序列中,能够满足任意前缀序列中 0 的个数都不少于 1
的个数的序列有多少个。输出的答案对 109+7取模。
思路
在这里插入图片描述
将问题转换为从左下角走到右上角,0往右走,1往上走。就是总的路径数减去经过上红线的路径数。经过上红线的路径按上红线进行对称,一定能走到(n-1,n+1)
即计算 C 2 n n − C 2 n n − 1 C_{2n}^n-C_{2n}^{n-1} C2nnC2nn1的值
卡特兰定理:

C 2 n n − C 2 n n − 1 = ( 2 n ) ! n ! n ! − 2 n ! ( n − 1 ) ! ( n + 1 ) ! = 2 n ! n ! ( n + 1 ) ! = 1 n + 1 2 n ! n ! n ! = 1 n + 1 C 2 n n C_{2n}^n-C_{2n}^{n-1}= \frac {(2n)!} {n!n!}-\frac{2n!}{(n-1)!(n+1)!}=\frac {2n!}{n!(n+1)!}=\frac{1}{n+1} \frac {2n!}{n!n!}=\frac{1}{n+1}C_{2n}^{n} C2nnC2nn1=n!n!(2n)!(n1)!(n+1)!2n!=n!(n+1)!2n!=n+11n!n!2n!=n+11C2nn

接下来就是计算组合数的问题。

#include<iostream>

using namespace std;

typedef long long LL;
const LL mod = 1e9+7;

int n;

LL qmi(LL a,LL p,LL q){
	//快速幂求逆元
    LL res=1;
    while(p){
        if(p&1) res=res*a%q;
        a=a*a%q;
        p>>=1;
    }
    return res;
}

int main(){
    cin>>n;
    LL res=1;
    for(int i=2*n;i>n;i--) res=res*i%mod;
    for(int i=n;i>0;i--) res=res*qmi(i,mod-2,mod)%mod;
    res=res*qmi(n+1,mod-2,mod)%mod;
    cout<<res<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值