解题思路
因为每次横纵坐标至少(+1),所以可以枚举走的步数,枚举走的步数(i)后剩下的就是把(n-1)与(m-1)划分成(i)个有序正整数相加,所以用隔板法,(ans=sumlimits_{i=1}^{min(n,m)-1} C(n-2,i-1)*C(m-2,i-1))
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int MAXN = 100005;
const int MOD = 1e9+7;
typedef long long LL;
int n,m,fac[MAXN],inv[MAXN];
LL ans;
int fast_pow(int x,int y){
int ret=1;
for(;y;y>>=1){
if(y&1) ret=(LL)ret*x%MOD;
x=(LL)x*x%MOD;
}
return ret;
}
inline LL C(int x,int y){
if(x<y) return 0;
return (LL)fac[x]*inv[y]%MOD*inv[x-y]%MOD;
}
int main(){
scanf("%d%d",&n,&m);int Max=max(n,m),Min=n+m-Max;fac[0]=1;
for(int i=1;i<=Max;i++) fac[i]=(LL)fac[i-1]*i%MOD;
inv[Max]=fast_pow(fac[Max],MOD-2);
for(int i=Max-1;~i;i--) inv[i]=(LL)inv[i+1]*(i+1)%MOD;
for(int i=1;i<Min;i++) ans=(ans+(LL)C(n-2,i-1)*C(m-2,i-1)%MOD)%MOD;
printf("%lld
",ans);
return 0;
}