2018.09.25 bzoj1856: [Scoi2010]字符串(组合数学)

传送门

如果有n==m的条件就是卡特兰数。

但现在n不一定等于m。

我们可以考虑用求卡特兰数一样的方法来求答案。

我们知道有一种求卡特兰数的方法是转到二维平面求答案。

这道题就可以这样做。

我们将这个序列映射到二维平面上。

相当于从(0,0)(0,0)(0,0)出发,每次只能向右上方或者向右下方走对应着选1/0,最后应该停在(n+m,n−m)(n+m,n-m)(n+m,n−m)。

但这样会出现非法状态。

如何排除?

我们发现如果出现非法状态一定会穿过直线y=−1y=-1y=−1,这样我们把图像关于y=−1y=-1y=−1翻折,起点就变成了(0,−2)(0,-2)(0,−2)。

这样总方案数是(n+mn)\binom {n+m} {n}(nn+m​),不合法的就是(n+mm−1)\binom {n+m} {m-1}(m−1n+m​)。

代码:

#include<bits/stdc++.h>
#define mod 20100403
#define ll long long
using namespace std;
inline ll ksm(ll x,int p=mod-2,ll ret=1){
	while(p){
		if(p&1)ret=ret*x%mod;
		x=x*x%mod,p>>=1;
	}
	return ret;
}
ll n,m;
inline ll C(ll x,ll y){
	ll ret=1,tmp=1;
	for(int i=1;i<=x;++i)ret=ret*i%mod;
	for(int i=1;i<=y;++i)tmp=tmp*i%mod;
	(ret*=ksm(tmp))%=mod,tmp=1;
	for(int i=1;i<=x-y;++i)tmp=tmp*i%mod;
	return (ret*ksm(tmp))%mod;
}
int main(){
	scanf("%lld%lld",&n,&m);
	printf("%lld",(C(n+m,n)-C(n+m,m-1)+mod)%mod);
	return 0;
}
上一篇:POJ2068 Nim 博弈论 dp


下一篇:2018.09.01 poj3071Football(概率dp+二进制找规律)