基准时间限制:
51nod 1119 机器人走方格 V2 (组合数学+逆元) 收藏
51nod 1119 机器人走方格 V2 (组合数学+逆元) 关注
51nod 1119 机器人走方格 V2 (组合数学+逆元) 取消关注
M * N的方格,一个机器人从左上走到右下,只能向右或向下走。有多少种不同的走法?由于方法数量可能很大,只需要输出Mod 10^9 + 7的结果。
 
Input
Output
Input示例
Output示例
3


分析:因为只能向下或向右走,所以从格子(1,1)走到格子(n,m)需要向下走n-1步、向右走m-1步。一共是n-1+m-1步,不同的方案在于什么时候走向下的(n-1)步,所以是C(n-1+m-1,n-1).

而要对组合数取模,即对除法取模是不能直接在商后面取模的,只有乘法满足(a*b)%m=(a%m)*(b%m)%m.所以呢,将除法变乘法,也就是说求出除数的乘法逆元。

求乘法逆元,方法很多。比较好理解的就是费马小定理:a的乘法逆元k(a*k%mod=1)的值为a^(mod-2).这是当mod为素数的时候。不为素数呢?等于a^(phi(mod)-). phi(mod)指mod的欧拉函数值。


#include <iostream>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;//是素数
ll pow(ll a,ll i)
{
    ll ans=1;
    while(i)
    {
        if(i&1)
            ans=ans*a%mod;
        i>>=1;
        a=a*a%mod;
    }
    return ans;
}
ll jc(ll n)
{
    ll ans=1;
    for(ll i=1;i<=n;i++)
        ans=ans*i%mod;
    return ans;
}
ll C(ll n,ll m)
{
    ll ans=1;
    ans=ans*jc(n)%mod;
    ans=ans*pow(jc(m),mod-2)%mod;
    ans=ans*pow(jc(n-m),mod-2)%mod;
    return ans;
}
int main()
{
    ios::sync_with_stdio(false);
    int m,n;
    while(cin>>m>>n)
    {
        cout<<C(m-1+n-1,n-1)<<endl;
    }
    return 0;
}

  

相关文章:

  • 2022-01-21
  • 2022-12-23
  • 2022-12-23
  • 2021-10-05
  • 2021-12-02
  • 2021-12-03
  • 2022-01-08
  • 2021-11-23
猜你喜欢
  • 2021-09-19
  • 2021-07-05
  • 2021-07-25
  • 2021-12-09
  • 2022-12-23
  • 2022-12-23
  • 2021-04-20
相关资源
相似解决方案