Codeforces 1324E Sleeping Schedule

题目链接

每一次选择\(a_i / a_i-1\)都会对以后的选择有影响, 那就是经典的DP问题, 找最优子结构, 设\(dp_{i,j}\)为已经经过\(i\)次, 有\(j\)次选择了\(a_i-1\)的最优次数, 设\(sum_i=\sum_0^i a_i\), 得到状态转移:
\(dp_{i+1, j} = max(dp_{i, j} + l≤(sum-j)\%h ≤ r))(0≤j≤i)\)
\(dp_{i+1, j+1} = max(dp_{i, j} + l≤(sum-j-1)\%h ≤ r))(0≤j≤i)\)

#include<bits/stdc++.h>
using namespace std;
#define ms(x,y) memset(x, y, sizeof(x))
#define lowbit(x) ((x)&(-x))
typedef long long LL;
typedef pair<int,int> pii;

const int INF = 0x3f3f3f3f;

int isgood(int t, int l, int r) {
    return t >= l && t <= r;
}

void run_case() {
    int n, h, l, r;
    cin >> n >> h >> l >> r;
    vector<vector<int>> dp(n+1, vector<int>(n+1, -INF));
    dp[0][0] = 0;
    vector<int> a(n);
    for(auto &x: a) cin >> x;
    int sum = 0;
    for(int i = 0; i < n; ++i) {
        sum += a[i];
        for(int j = 0; j <= i; ++j) {
            dp[i+1][j] = max(dp[i+1][j], dp[i][j] + isgood((sum-j)%h, l, r));
            if(j < n) dp[i+1][j+1] = max(dp[i+1][j+1], dp[i][j] + isgood((sum-j-1)%h, l, r));
        }
    } 
    cout << *max_element(dp[n].begin(), dp[n].end());

}

int main() {
    ios::sync_with_stdio(false), cin.tie(0);
    cout.flags(ios::fixed);cout.precision(2);
    //int t; cin >> t;
    //while(t--)
    run_case();
    cout.flush();
    return 0;
}
posted @ 2020-03-13 17:24  GRedComeT  阅读(142)  评论(0编辑  收藏  举报