• 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;
    }
    
  • 相关阅读:
    牛客-编程题
    Python 实现一键发布项目
    IDEA MyBatis Log Plugin 收费了,这个可以替代用
    微信 for Windows 内测3.3.0版本,能刷朋友圈啦!
    实况摄像头,“偷窥” 世界美景!
    阿里云盘PC/MAC客户端内测版
    我十年前的工位 vs 我现在的工位
    设置电脑屏保全屏显示时间,酷!
    自我介绍
    Bartender 处理日期格式化
  • 原文地址:https://www.cnblogs.com/Chen-Jr/p/11007266.html
Copyright © 2020-2023  润新知