• 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;
    }
    
  • 相关阅读:
    MySQL_01 常用命令
    32_Go基础(TCP通信)
    oracle查询优化
    Eclipse中自动添加注释(作者,时间)
    java注解的学习
    JqueryeasyUIdatagrid参数之 queryParams
    Eclipse中,打开文件所在文件夹的插件,及设置
    更改Zend Studio/Eclipse代码风格主题
    JAVA中使用File类批量重命名文件及java.io.File的常见用法
    java面试笔试题大全
  • 原文地址:https://www.cnblogs.com/Chen-Jr/p/11007266.html
Copyright © 2020-2023  润新知