传送门
组合数学好题。
给你一个
h
h
h行
w
w
w列的网格,其中左下角
a
a
a行
b
b
b列不能走,问从左上角走到右下角有多少种走法(每次只能向右或者向下)
我们考虑分步计数。
我们一共能走的区域是总网格区域去掉一个左下角的,可以看成是一个
b
∗
(
h
−
a
)
b*(h-a)
b∗(h−a)的矩形和一个
h
∗
(
w
−
b
)
h*(w-b)
h∗(w−b)的矩形拼起来的图案。
于是我们可以枚举两个矩形的交界处来统计答案。
相当于是分步走。
先从起点走到交界处,然后从交界处走到终点。
代码:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
typedef long long ll;
const int N=2e5+5,mod=1e9+7;
int h,w,a,b,fac[N],ifac[N],ans=0,up;
inline int C(int n,int m){return (ll)fac[n]*ifac[m]%mod*ifac[n-m]%mod;}
int main(){
scanf("%d%d%d%d",&h,&w,&a,&b),up=max(w,h),fac[0]=fac[1]=ifac[0]=ifac[1]=1;
for(ri i=2;i<=up<<1;++i)fac[i]=(ll)fac[i-1]*i%mod,ifac[i]=(ll)ifac[mod%i]*(mod-mod/i)%mod;
for(ri i=2;i<=up<<1;++i)ifac[i]=(ll)ifac[i]*ifac[i-1]%mod;
for(ri i=1;i<=h-a;++i)(ans+=(ll)C(b+i-2,b-1)*C(h+w-b-i-1,w-b-1)%mod)%=mod;
cout<<ans;
return 0;
}