• E:Sleeping Schedule(DP)


    Sleeping Schedule

    思路

    这道题读题就感觉像时(DP),读完题后更加坚定了,这是一道(DP)题目。

    我们考虑状态转移方程,(dp[i][j])表示在第(i)次入睡时间是(j)的时候的时间最优值,所以显然有我们的状态转移方程就是

    (dp[i][(j + a[i]) \% n] = max((dp[i][j + a[i]) \% n), dp[i - 1][j] + 1),这里的j枚举的是上一次入睡的时间,因为是睡一天嘛,所以下一次睡觉的时间就是((j + a[i]) \% b)

    当然这里并没有考虑完备,因为我们还有一个时间时是((j + a[i] - 1) \% n),但是转移过程跟上面是一样的,这里就不多列式子了。

    接下来我在代码里说一些我wa过得坑点。

    代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    
    inline ll read() {
        ll f = 1, x = 0;
        char c = getchar();
        while(c < '0' || c > '9') {
            if(c == '-') f = -1;
            c = getchar();
        } 
        while(c >= '0' && c <= '9') {
            x = (x << 1) + (x << 3) + (c ^ 48);
            c = getchar();
        }
        return f * x;
    }
    
    const int N = 2e3 + 10;
    
    int dp[N][N], a[N], n, h, l, r;
    
    int main() {
        // freopen("in.txt", "r", stdin);
        // freopen("out.txt", "w", stdout);
        // ios::sync_with_stdio(false);
        n = read(), h = read(), l = read(), r = read();
        for(int i = 1; i <= n; i++)
            a[i] = read();
        memset(dp, -1, sizeof dp);//初始化,
        dp[0][0] = 0;//只有这个状态是合理的,所以初始化为0.
        for(int i = 1; i <= n; i++)
            for(int j = 0; j < h; j++) {//昨天是在j时入睡的,
                if(dp[i - 1][j] < 0)    continue;//只能从上面一个合理的状态转移过来,所以上一个状态一定要满足是>= 0的,
                if((a[i] + j) % h >= l && (a[i] + j) % h <= r)//隔a[i]
                    dp[i][(a[i] + j) % h] = max(dp[i][(a[i] + j) % h], dp[i - 1][j] + 1);
                else
                    dp[i][(a[i] + j) % h] = max(dp[i][(a[i] + j) % h], dp[i - 1][j]);
                if((a[i] + j - 1) % h >= l && (a[i] + j - 1) % h <= r)//隔a[i] - 1
                    dp[i][(a[i] + j - 1) % h] = max(dp[i][(a[i] + j - 1) % h], dp[i - 1][j] + 1);
                else
                    dp[i][(a[i] + j - 1) % h] = max(dp[i][(a[i] + j - 1) % h], dp[i - 1][j]);
            }
        int ans = 0;
        for(int i = 0; i < h; i++)//从0 ~ h - 1枚举,并不是1 ~ n,这点一定注意。
            ans = max(ans, dp[n][i]);
        printf("%d
    ", ans);
        return 0;
    }
    
  • 相关阅读:
    安卓apk反编译、修改、重新打包、签名全过程
    Win10解决无法访问其他机器共享的问题
    VMware Pro v14.1.1 官方版本及激活密钥
    java发送http的get/post请求(一)
    Git忽略规则及.gitignore规则不生效的解决办法
    RouterOS视频教程下载
    Socket心跳包异常检测的C语言实现,服务器与客户端代码案例
    去掉Word 标题编号变成黑框
    【分布式】分布式系统中的幂等性
    java反射(Reflection)的使用
  • 原文地址:https://www.cnblogs.com/lifehappy/p/13068881.html
Copyright © 2020-2023  润新知