Submission #673663

#TimeUsernameProblemLanguageResultExecution timeMemory
673663stanislavpolynThe short shank; Redemption (BOI21_prison)C++17
45 / 100
285 ms107520 KiB
#include <bits/stdc++.h>
 
#define fr(i, a, b) for (int i = (a); i <= (b); ++i)
#define rf(i, a, b) for (int i = (a); i >= (b); --i)
#define fe(x, y) for (auto& x : y)
 
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define mt make_tuple
 
#define all(x) (x).begin(), (x).end()
#define pw(x) (1LL << (x))
#define sz(x) (int)(x).size()
 
using namespace std;
 
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
template <typename T>
using oset = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
#define fbo find_by_order
#define ook order_of_key
 
template <typename T>
bool umn(T& a, T b) { return (a > b ? (a = b, 1) : 0); }
template <typename T>
bool umx(T& a, T b) { return (a < b ? (a = b, 1) : 0); }
 
using ll = long long;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
template <typename T>
using ve = vector<T>;
 
const int N = 5e5 + 5;
const int M = 5005;
 
int n, d, T;
int cost[M][M];
int opt[M][M];
int dp[M][M];
int a[N];
int p[N];
 
ve<int> del[N];
set<int> s;
 
int main() {
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#else
    ios::sync_with_stdio(0);
    cin.tie(0);
#endif
//
//    cout << 30 * 4000 * 4000 / 1e8 << "\n";
//
//    return 0;
 
    cin >> n >> d >> T;
 
    fr (i, 1, n) {
        cin >> a[i];
    }
 
    {
        fr (i, 1, n) {
            fe (cur, del[i]) s.erase(cur);
            if (a[i] <= T) {
                s.insert(i);
                if (i + T - a[i] + 1 <= n) {
                    del[i + T - a[i] + 1].pb(i);
                }
            }
            p[i] = sz(s) ? *s.rbegin() : -1;
        }
    }
 
    if (d == 1) {
        multiset<int> s;
        fr (i, 1, n) {
            s.insert(p[i]);
        }
        int ans = 0;
        int best = 1e9;
        fr (i, 1, n) {
            while (sz(s) && *s.begin() < i) {
                s.erase(s.begin());
            }
 
            umn(best, ans + sz(s));
 
            if (p[i] >= 1) {
                ans++;
            }
            if (s.find(p[i]) != s.end()) {
                s.erase(s.find(p[i]));
            }
        }
 
        cout << best << "\n";
        return 0;
    }
 
//    fr (i, 1, n) cout << p[i] << " ";
//    cout << "\n";
 
    if (n <= 4000) {
        fr (i, 1, n) {
            int ans = 0;
            fr (j, i, n) {
                if (p[j] >= i) {
                    ans++;
                }
                cost[i][j] = ans;
            }
        }
 
 
        fr (i, 1, n) {
            fr (j, 1, d + 1) {
                dp[i][j] = 1e9;
            }
        }
 
        fr (i, 1, n) {
            dp[i][1] = cost[1][i];
            opt[i][1] = 0;
        }
 
        fr (j, 2, d + 1) {
            opt[n + 1][j] = n - 1;
 
            rf (i, n, 1) {
                fr (p, opt[i][j - 1], opt[i + 1][j]) {
                    if (umn(dp[i][j], dp[p][j - 1] + cost[p + 1][i])) {
                        opt[i][j] = p;
                    }
                }
            }
        }
 
 
 
//        fr (i, 1, n) {
//            fr (was, 1, min(i, d)) {
//                fr (j, i + 1, n) {
//                    umn(dp[j][was + 1], dp[i][was] + cost[i + 1][j]);
//                }
//            }
//        }
//
        cout << dp[n][d + 1] << "\n";
        return 0;
    }
 
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...