zoukankan      html  css  js  c++  java
  • 51nod 1119 机器人走方格 V2 (组合数学+逆元)

    基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题
    收藏
    关注
    取消关注
    M * N的方格,一个机器人从左上走到右下,只能向右或向下走。有多少种不同的走法?由于方法数量可能很大,只需要输出Mod 10^9 + 7的结果。
     
    Input
    第1行,2个数M,N,中间用空格隔开。(2 <= m,n <= 1000000)
    Output
    输出走法的数量 Mod 10^9 + 7。
    Input示例
    2 3
    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;
    }
    

      

  • 相关阅读:
    gRPC .NET Core跨平台学习
    .NET Core性能测试组件BenchmarkDotNet 支持.NET Framework Mono
    ASP.NET Core中间件(Middleware)实现WCF SOAP服务端解析
    gRPC C#学习
    中标麒麟关闭防火墙
    linux安装python
    python matplotlib.pyplot保存jpg图片失败
    python正态分布
    数据健康管理总结
    python使用statsmodel
  • 原文地址:https://www.cnblogs.com/onlyli/p/7300870.html
Copyright © 2011-2022 走看看