20 ACwing 288 休息时间 题解

休息时间

题面

在某个星球上,一天由 N 个小时构成,我们称 0 点到 1 点为第 1 个小时、1 点到 2 点为第 2 个小时,以此类推。

在第 i 个小时睡觉能够恢复 \(U_i\) 点体力。

在这个星球上住着一头牛,它每天要休息 B 个小时。

它休息的这 B 个小时不一定连续,可以分成若干段,但是在每段的第一个小时不能恢复体力,从下一个小时开始才能睡着,从而恢复体力。

为了身体健康,这头牛希望遵循生物钟,每天采用相同的睡觉计划。

另外,因为时间是连续的,即每一天的第 N 个小时和下一天的第 1 个小时是相连的(N 点等于 0 点),这头牛只需要在每 N 个小时内休息够 B 个小时就可以了。

请你帮忙给这头牛安排一个睡觉计划,使它每天恢复的体力最多。

\(3 \le N \le 3830\)

\(2 \le B < N\)

\(0 \le U_i \le 2 \times 10^5\)

题解

如果先不考虑两天连着的这个条件,只考虑这一天里该怎么睡

我们需要知道一共睡了多长时间,以及前一小时睡没睡

所以设 \(f(i,j,0/1)\) 表示到第 \(i\) 小时,已经睡了 \(j\) 小时,第 \(i\) 个小时睡/没睡,能获得的最大体力

因为我们不考虑前一天的小时,所以这天的第一个小时一定没有贡献,初始状态 \(f(1, 0, 0) = 0, \ f(1, 1, 1) = 0\) ,目标状态 \(max\{f(N,B,0), \ f(N,B,1)\}\) 转移:

\[\begin{align} & f(i, j, 0) = max \{ f(i - 1, j, 0), \ f(i - 1, j, 1) \} \\ & f(i, j, 1) = max \{ f(i - 1, j - 1, 0), \ f(i - 1, j - 1, 1) + U_i \} \end{align} \]

这样dp就只少了一种第一个小时有贡献的情况,所以我们可以再做一个dp ,强制前一天的第 \(N\) 个小时以及这一天的第一个小时选,初始 \(f(1, 1, 1) = U_i\) ,转移同上,最终答案在两种情况中取个最大值即可

时间复杂度为 \(O(NB)\)

code

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>

using namespace std;

const int N = 3835;

int n, m;
int f[N][2], val[N];

int main () {

    cin >> n >> m;
    for (int i = 1; i <= n; i ++) {
        cin >> val[i];
    }
    //只考虑当天的情况
    memset (f, -0x3f, sizeof f);
    f[0][0] = f[1][1] = 0;
    for (int i = 2; i <= n; i ++) {
        for (int j = min (i, m); j >= 0; j --) {
            f[j][0] = max (f[j][0], f[j][1]);
            if (j) {
                f[j][1] = max (f[j - 1][0], f[j - 1][1] + val[i]);
            }
        }
    }
    int ans = max (f[m][0], f[m][1]);
    
    //强制跨天的情况
    memset (f, -0x3f, sizeof f);
    f[1][1] = val[1];
    for (int i = 2; i <= n; i ++) {
        for (int j = min (i, m); j >= 0; j --) {
            f[j][0] = max (f[j][0], f[j][1]);
            if (j) {
                f[j][1] = max (f[j - 1][0], f[j - 1][1] + val[i]);
            }
        }
    }
    //因为强制跨天,所以最后一天一定会选,所以 f[m][0] 是不合法状态
    ans = max (ans, f[m][1]);
    cout << ans << endl;

    return 0;
}
posted @ 2025-10-05 18:01  michaele  阅读(6)  评论(0)    收藏  举报