D-公园游玩
看了题目一看是要求遍历所有点的最短路径方法数,心想着去求最短路径,结果tmd根本不用求,只需要把输入时相邻的每两个点的方法数相乘就是结果了;
接下来说一下怎么求两点之间最短路径的方案数,从a(x1,y1),b(x2,y2),从a到b至少要走|x1-x2|+|y1-y2|步,其中要沿着x轴移动|x1-x2|步,沿着y轴移动|y1-y2|步,什么时候沿着x轴移动或沿着y轴移动无关紧要,关键是要在x轴或y轴移动这么多的步数,那就牵扯到组合问题了,就是在|x1-x2|+|y1-y2|中找出|x1-x2|个数的组合方法;
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const LL MOD=1e9+7;
const int N=2e5+10;
LL f[N];
LL n,m,k;
LL res=1;
LL qmi(LL a,LL b)//快速幂
{
LL res=1;
while(b)
{
if(b&1)res=res*a%MOD;
b=b/2;
a=a*a%MOD;
}
return res%MOD;
}
LL get(LL y,LL x)//求组合数
{
return (f[y+x]%MOD)*qmi(f[x]*f[y]%MOD,MOD-2)%MOD;//万能费马小定理
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n>>m>>k;
f[0]=1;
for(int i=1; i<=n+m; i++)f[i]=f[i-1]*i%MOD;
LL x,y;
x=y=1;
while(k--)
{
LL a,b;
cin>>a>>b;
res=res*get(abs(a-x),abs(b-y))%MOD;
x=a;
y=b;
}
res=res*get(abs(n-x),abs(m-y))%MOD;
cout<<res<<endl;
return 0;
}