[SCOI2010]字符串(卡特兰数,组合数学)

[SCOI2010]字符串 (nowcoder.com)

题目描述

lxhgww最近接到了一个生成字符串的任务,任务需要他把n个1和m个0组成字符串,但是任务还要求在组成的字符串中,在任意的前k个字符中,1的个数不能少于0的个数。现在lxhgww想要知道满足要求的字符串共有多少个,聪明的程序员们,你们能帮助他吗?

输入描述:

输入数据是一行,包括2个数字n和m

输出描述:

输出数据是一行,包括1个数字,表示满足要求的字符串数目,这个数可能会很大,只需输出这个数除以20100403的余数

示例1

输入

复制2 2

2 2

输出

复制2

2

备注:

对于30%的数据,保证 1≤m≤n≤1e3
对于100%的数据,保证 1≤m≤n≤1e6 

思路:

首先普及一下卡特兰数:

给出一个n*n的正方形棋盘,求从左下角到右上角的不经过对角线的所有走法刚好是F[n],即C(2n, n)-C(2n, n-1)

然而对于这一题,可以想想象成,从(0,0)走到(n+m,n)不向下走,1代表向上,0代表向下,根据卡特兰数,可以得出最后的方案数是C(n+m,m)-C(n+m,m-1)

AC代码:

#include<bits/stdc++.h>
#define lmw ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
#define int long long
const int mod=20100403;
const int N=2e6+10;
int inf[N],f[N];
int n,m;
int ksm(int x,int y){
	int res=1;
	while(y){
		if(y&1){
			res=res*x%mod;
		}
		y/=2;
		x=x*x%mod;
	}
	return res%mod;
}
int C(int x ,int y){
	return f[x]*inf[y]%mod*inf[x-y]%mod;
}
inline void init(){
	f[0]=1;
	for(int i=1;i<=n+m;i++){
		f[i]=f[i-1]*i%mod;
	}
	inf[n+m]=ksm(f[n+m],mod-2);
	for(int i=n+m-1;i>=0;i--){
		inf[i]=inf[i+1]*(i+1)%mod;
	}
} 
signed main(){
	lmw;
//	int n,m;
	cin>>n>>m;
	init();
	if(n<m) {
		cout<<"0\n"; 
	}
	else {
		cout<<(C(n+m,m)-C(n+m,m-1)+mod)%mod<<"\n";
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值