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

    题目链接:

    1119 机器人走方格 V2

     

    基准时间限制:1 秒
    空间限制:131072 KB 
     

     

    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


    题意:

    中文的就不说了;

    思路:

    这题用dp的思想是这样的,dp[i][j]=dp[i-1][j]+dp[i][j-1];这种是i,j分别表示i行j列;
    我们来转换一下,p[x][j表示第x-j行第j列的方案数,那么p和dp之间的关系是什么样的呢?

    p[i][j]=dp[i-j-1][j]+dp[i-j][j-1]=p[i-1][j]+p[i-1][j-1];
    p[i][j]=p[i-1][j]+p[i-1][j-1];诶?这个东西好熟悉啊啊啊;让我想想在哪见过......
    哈哈哈哈,这就是组合数的递推公式啊,Ci,j=Ci-1,j+Ci-1,j-1;
    所以答案就是Cn+m-2,n;
    然后就是求乘法逆元和快速幂了;


    AC代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e6+5;
    typedef long long ll;
    const ll mod=1e9+7;
    ll dp[2*N];
    void Iint()
    {
        dp[1]=1;
        for(int i=2;i<=200000;i++)
        {
            dp[i]=(dp[i-1]*(ll)i)%mod;
        }
    }
    ll n,m;
    ll fast_pow(ll a,ll b)//快速幂;
    {
        ll s=1,base=a;
        while(b)
        {
            if(b&1)
            {
                s*=base;
                s%=mod;
            }
            base *= base;
            base%=mod;
            b=(b>>1);
        }
        return s;
    }
    int main()
    {
        Iint();
         while(scanf("%lld%lld",&n,&m)!=EOF)
        {
            n--;
            m--;
            ll x=dp[n]*dp[m]%mod;
            ll ans=dp[n+m]*fast_pow(x,mod-2)%mod;
            printf("%lld
    ",ans);
        }
    
        return 0;
    }

     

  • 相关阅读:
    etcd扩展使用
    etcd注册服务
    net core微服务构建方案
    一个简化的插件框架c#
    NSQ消息队列
    c#一些处理解决方案(组件,库)
    c#网络传输
    c#的传输组件dotnetty
    c#网络加密传输
    C++ Boost在Windows和Linux下的编译安装
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/5404386.html
Copyright © 2011-2022 走看看