CodeForces-1324E-Sleeping-Schedule

题意

(Vova)有一个睡眠时间表,一天有(h)小时,(Vova)会睡(n)次觉,一次睡一天,在第(i-1)次睡醒后,(Vova)(a_i)(a_i-1)个小时候可以再次入睡,一开始时间为第(0)时(可以视作(Vova)刚醒),(Vova)([l,r])区间时睡觉会睡得舒服,问(Vova)最多可以睡几次舒服觉

分析

发现第(i)次睡眠的时间是由第(i-1)次睡眠时间决定的,一个显然的转移,因此这道题采用(DP)

首先我们可以设第(0)次睡眠时,(Vova)是在第(0)时刻睡的

假设(Vova)在第(i-1)次睡眠时在第(j)时刻,那么第(i)(Vova)可以在第((j+a_i)\%h)时刻或者在第((j+a_i-1)\%h)时刻睡觉,我们可以记录一个(vis[i][j])表示(Vova)在第(i)次睡眠时在第(j)时刻可以睡

而如果((j+a_i)\%h)([l,r])区间内,则第(i)次睡眠在第((j+a_i)\%h)时刻的答案数为第(i-1)次睡眠时(j)时刻的答案数加一,因为有多种方案使得(Vova)能在第(i-1)次睡眠时在第(j)时刻,因此取最大值,可以记录(dp[i][j])表示在第(i)次睡眠时在第(j)时刻的答案,(dp[i][(j+a_i)\%h]=max(dp[i-1][j]+1,dp[i][(j+a_i)\%h]))

如果((j+a_i)\%h)不在([l,r])区间内,则(dp[i][(j+a_i)\%h]=max(dp[i-1][j],dp[i][(j+a_i)\%h]))

答案可以在每次更新(dp[i][j])时更新

((j+a_i-1)\%h)同理

这题不卡空间,可以不使用滚动数组

#pragma GCC optimize(3, "Ofast", "inline")

#include <bits/stdc++.h>

#define start ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define int ll
#define ls st<<1
#define rs st<<1|1
#define pii pair<int,int>
using namespace std;
const int maxn = (ll) 3e5 + 5;
const int mod = 1000000007;
const int inf = 0x3f3f3f3f;
int dp[2005][2005];
bool vis[2005][2005];
int ans;

signed main() {
    start;
    int n, h, l, r;
    cin >> n >> h >> l >> r;
    vis[0][0] = true;
    for (int i = 1; i <= n; ++i) {
        int x;
        cin >> x;
        for (int j = 0; j < 2000; ++j) {
            if (vis[i - 1][j]) {
                int t = (j + x) % h;
                vis[i][t] = true;
                if (t >= l && t <= r)
                    dp[i][t] = max(dp[i][t], dp[i - 1][j] + 1);
                else
                    dp[i][t] = max(dp[i][t], dp[i - 1][j]);
                ans = max(ans, dp[i][t]);
                t = (j + x - 1) % h;
                vis[i][t] = true;
                if (t >= l && t <= r)
                    dp[i][t] = max(dp[i][t], dp[i - 1][j] + 1);
                else
                    dp[i][t] = max(dp[i][t], dp[i - 1][j]);
                ans = max(ans, dp[i][t]);
            }
        }
    }
    cout << ans;
    return 0;
}
原文地址:https://www.cnblogs.com/F-Mu/p/12485060.html