zoukankan      html  css  js  c++  java
  • 2018牛客暑假多校二 A(dp)

    题目描述:

        你在健身,每秒可以走1米或跑k米,并且不能连续2秒都在跑。当它的移动距离在[L,R]之间,可以选择结束锻炼。问由多少种方案

    题目分析:

        对于这个问题,因为对于每个时刻,我们可以走1米或者跑k米,因此我们不难想到这道题应该使用dp去解决。我们设dp数组dp[i][j],其中i和j分别表示到了第i米时,是由第j中方式走过来的(其中j==0代表走1米过来的,j==1代表跑k米过来的)。

        因此我们就可以分两种情况进行状态转移。不难发现,当j==0时,此时的状态即可以由前一时刻的j==0或j==1的状态分别转移过来,因此我们可以列出状态转移方程:dp[i][0]=(dp[i][0]+dp[i-1][0])%mod;dp[i][0]=(dp[i][0]+dp[i-1][1])%mod;

        同理,当j==1时,我们也可以列出状态转移方程:dp[i][1]=(dp[i][1]+dp[i-k][0])%mod;

        最后,因为我们需要求的是L到R区间的值,因此我们只需要用前缀和去维护即可。

    代码:

    #include <bits/stdc++.h>
    #define maxn 100005
    using namespace std;
    typedef long long ll;
    ll sum[maxn];
    ll dp[maxn][2];
    const ll mod=1e9+7;
    int main()
    {
        int n,k;
        cin>>n>>k;
        int l,r;
        dp[0][0]=1;
        for(int i=1;i<maxn;i++){
            dp[i][0]=(dp[i][0]+dp[i-1][0])%mod;
            dp[i][0]=(dp[i][0]+dp[i-1][1])%mod;
            if(i>=k) dp[i][1]=(dp[i][1]+dp[i-k][0])%mod;
            sum[i]=(sum[i-1]+dp[i][0]+dp[i][1])%mod;
        }
        for(int i=1;i<=n;i++){
            cin>>l>>r;
            ll res=(sum[r]-sum[l-1]+mod)%mod;
            printf("%lld
    ",res);
        }
        return 0;
    }
    
  • 相关阅读:
    CSS hacks汇总
    都要靠自己
    不被需要
    我们都是和自己赛跑的人
    其实天底下只有三件事
    开始怀旧了
    JavaScript回调函数陷阱
    郁闷着继续
    清明节悼念逝去亲人
    纯div+css制作的弹出菜单
  • 原文地址:https://www.cnblogs.com/Chen-Jr/p/11007266.html
Copyright © 2011-2022 走看看