题目链接:https://atcoder.jp/contests/arc058/tasks/arc058_b
题意:
给你一个n*m的网格,该网格的左下角的a*b的网格不能走,求从(1,1)到(n,m)有多少种走法(结果模上1e9)
思路:先从(1,1)走到(n-a,i)(i从b+1到m)然后再往下走一步(这里不能再往右走了否则会重复计算)然后到(n,m);
代码:
#include<bits/stdc++.h>
#define LL long long
#define maxn 1000000
using namespace std;
const LL MOD = 1e9+7;
LL fact[maxn+5];
LL a[maxn+10];
LL pow(LL x)
{
LL n = MOD-2;
LL res=1;
while(n>0)
{
if(n%2==1)
res=res*x%MOD;
x=x*x%MOD;
n>>=1;
}
return res;
}
void init(){
a[0] = a[1] = 1;
fact[0] = fact[1] = 1;
for(int i = 2; i <= 1000005; i++)
{
fact[i] = fact[i-1] * i % MOD;
a[i] = a[i-1] * pow(i) % MOD;
}
}
LL C(LL n, LL m){
if(n<0||m<0||n<m)return 0;
return fact[n]*a[n-m]%MOD*a[m]%MOD;
}
int main()
{
init();
LL n,m,a,b;
cin>>n>>m>>a>>b;
LL sum=0;
for(int i=b+1;i<=m;i++)
{
sum+=(C(n-a+i-2,i-1)*C(a+m-i-1,m-i))%MOD;
sum%=MOD;
}
cout<<sum%MOD<<endl;
}