zoukankan      html  css  js  c++  java
  • 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;
    }

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


    蒟蒻求大犇轻喷……

  • 相关阅读:
    数据结构(2)链表的实现
    vc 调试方法-2
    c语法拾遗-关于指针变量的声明
    收集的一些无聊的网站
    《将博客搬至CSDN》的文章
    黑马程序员-面向对象
    黑马程序员-类加载机制和反射。
    黑马程序员- 正则表达式
    黑马程序员-网络编程
    黑马程序员-File类+递归的简单应用
  • 原文地址:https://www.cnblogs.com/acerkoo/p/9490345.html
Copyright © 2011-2022 走看看