• Exam 5095 Hopscotch


    Hopscotch

    时间限制: 5 Sec  内存限制: 128 MB

    题目描述

    You’re playing hopscotch! You start at the origin and your goal is to hop to the lattice point (N, N). A hop consists of going from lattice point (x1, y1) to (x2, y2), where x1 < x2 and y1 < y2.
    You dislike making small hops though. You’ve decided that for every hop you make between two lattice points, the x-coordinate must increase by at least X and the y-coordinate must increase by at least Y .
    Compute the number of distinct paths you can take between (0, 0) and (N, N) that respect the above constraints. Two paths are distinct if there is some lattice point that you visit in one path which you don’t visit in the other.
    Hint: The output involves arithmetic mod 109+ 7. Note that with p a prime like 109+ 7, and x an integer not equal to 0 mod p, then x(xp−2) mod p equals 1 mod p.

    输入

    The input consists of a line of three integers, N X Y . You may assume 1 ≤ X, Y ≤ N ≤ 106.

    输出

    The number of distinct paths you can take between the two lattice points can be very large. Hence output this number modulo 1 000 000 007 (109+ 7).

    样例输入

    7 2 3
    

    样例输出

    9
    

    提示

    题意:从(0,0)处出发,走到目的地(n,n)。每走一步在x轴方向最少移动X距离,在y轴方向最少移动Y距离。求走到目的地的方案数。

    解题过程:

            刚开始想dp,但是数据范围比较大,就像通过一维DP实现二维操作,后来想了想不会……后来,发现好像能用组合数来做。就不断找组合数的公式,在推爆了好多次之后,选择分类讨论各种情况…但是各种RE。在老师标程中才了解了组合数公式——C(n-k*x+k-1,k-1)*C(n-k*y+k-1,k-1)。我们从1枚举到n/max(X,Y),并求和取模。

    求和过程大致如下:

    ll ans=0;
        for (int i=1;i<=t;i++){
            if(n-i*x+i-1<i-1||n-i*y+i-1<i-1) continue;
            ans+=C(n-i*x+i-1,i-1)*C(n-i*y+i-1,i-1)%mod,ans%=mod;
           // cout<<i<<" "<<ans<<endl;
        }

    过题代码如下:

    #include <cstdio>
    #include <cstring>
    #include <functional>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    const int maxn=1e6+10;
    const int mod = 1e9+7;
    typedef long long ll;
    ll Pow_mod(ll a,ll n){ll res=1;while(n){if(n&1)res=res*a%mod;a=a*a%mod;n>>=1;}return res;}
    ll fac[maxn];
    void init(){
        fac[0]=1;
    
        for (int i=1;i<maxn;i++) fac[i]=fac[i-1]*i%mod;
    }
    ll C(ll n,ll m){
        return  fac[n]*Pow_mod(fac[n-m]*fac[m]%mod,mod-2)%mod;
    }
    int main(){
        init();
        ll n,x,y;cin>>n>>x>>y;
        ll t=n/max(x,y);
        ll ans=0;
        for (int i=1;i<=t;i++){
            if(n-i*x+i-1<i-1||n-i*y+i-1<i-1) continue;
            ans+=C(n-i*x+i-1,i-1)*C(n-i*y+i-1,i-1)%mod,ans%=mod;
           // cout<<i<<" "<<ans<<endl;
        }
        cout<<ans<<endl;
        return 0;
    }

    其实在推组合数公式的过程中要保持冷静……不能老是思维爆炸……


    蒟蒻求大犇轻喷……

  • 相关阅读:
    python 01
    Node.js 基础库
    Node 编程规范
    Linux_异常_08_本机无法访问虚拟机web等工程
    inux_异常_07_ftp查看不到文件列表
    Linux_异常_04_ftp: command not found...
    Linux_异常_03_Failed to restart iptables.service: Unit not found.
    Linux_异常_02_WinSCP上传文件时显示Permission denied
    Linux_异常_01_CentOS7无法ping 百度
    Linux_配置_02_配置dns
  • 原文地址:https://www.cnblogs.com/acerkoo/p/9490345.html
Copyright © 2020-2023  润新知