P1641 [SCOI2010]生成字符串

本文通过一个具体的编程实例介绍了如何利用卡特兰数解决特定问题。通过对1和0字符序列的特殊规则进行分析,采用组合数学的方法,利用对称性原理,解决了不合法路径计数的问题,并给出了具体的C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

l类似卡特兰数的推理。当然要看题解啦!

可以考虑把1的个数与0的个数的和看成x坐标,1的个数与0的个数的差看成y坐标

向右上走(x坐标加1,y坐标加1)就表示这个字符选择1。

向右下走(x坐标加1,y坐标减1)就表示这个字符选择0。
这样子,如果不考虑限制条件,就表示从(0,0)走n+m步到达(n+m,n−m),这相当于从n+m步中选出m步向右下走,也就是C(n+m,m)。

考虑限制条件,任意前缀中11的个数不少于0的个数,也就是这条路径不能经过直线y=-1。可以通过对称性发现,从(0,0)走到直线y=-1上的一点,相当于从(0,-2)走到该点。也就是说,路径经过直线y=-1的方案数就是从(0,-2)走n+m步到达(n+m,n-m),这个方案数可以用组合数表示为C(n+m,m-1)。

参考代码:

#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
const int N=2e6+9,p=20100403;
ll n,m,f[N],inv[N] ;

ll qpow(ll a,ll b){
	ll ans=1;
	while(b){
		if(b&1)ans=ans*a%p;
		a=a*a%p;
		b/=2;
	}
	return ans;
}
ll c(ll n,ll m){
	ll ans=qpow(f[n-m],p-2)*qpow(f[m],p-2)%p;
	return ans=f[n]*ans%p;
}
int main() {	
	cin>>n>>m;
	f[0]=1,f[1]=1;
	for(int i=2;i<=n+m;i++)
		f[i]=i*f[i-1]%p;
	ll ans=(c(n+m,m)-c(n+m,m-1))%p;
	ans=(ans+p)%p;
	cout<<ans<<endl;
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值