得到组合公式:
C(m+n-4,n-2)或者是 C(m+n-4,m-2);
其中m+n-4表示是从m-2+n-2行和列的和中,选m-2列出来走(其中行也在走);或者说是
选n-2行出来走(其中列也在走);
求逆元:
C(m+n-4,n-2)或者是 C(m+n-4,m-2);
其中m+n-4表示是从m-2+n-2行和列的和中,选m-2列出来走(其中行也在走);或者说是
选n-2行出来走(其中列也在走);
求逆元:
利用扩展欧几里得算法;
#include<iostream>
using namespace std;
#define LL long long int
#define Mod 1000000007
void exgcd(LL a,LL b,LL &x,LL &y) // 扩展欧几里得算法;
{ //得到的x为解;
if(b==0)
{
x=1;
y=0;
return ;
}
LL x1,y1;
exgcd(b,a%b,x1,y1);
x=y1;
y=x1-(a/b)*y1;
}
int main()
{
LL i,j,k,m,n,sum;
while(cin>>n>>m)
{
sum=1;
for(i=1;i<=m+n-4;i++)
sum=(sum*i)%Mod; //算分子
for(i=1;i<=n-2;i++) // 算分母用欧几里得算法
{
LL x,y;
exgcd(i,Mod,x,y);
x=(x%Mod+Mod)%Mod;
sum=(sum*x)%Mod;
}
for(i=1;i<=m-2;i++)
{
LL x,y;
exgcd(i,Mod,x,y);
x=(x%Mod+Mod)%Mod;
sum=(sum*x)%Mod;
}
sum=(sum%Mod+Mod)%Mod;
cout<<sum<<endl;
}
return 0;
}