제출 #1331265

#제출 시각아이디문제언어결과실행 시간메모리
1331265lywoem구경하기 (JOI13_watching)C++20
100 / 100
453 ms30380 KiB
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define l(a, b, i) for (ll i = a; i < b; i++)
#define rl(a, b, i) for (ll i = a; i >= b; i--)
#define vpair vector<pair<ll, ll>>
#define inf LLONG_MAX
#define ninf LLONG_MIN

ll meow(ll N, ll W, ll P, ll Q, vector<ll> &vec) {
    vector<vector<ll>> dp(N + 1, vector<ll> (P + 1, inf)); // dp[i][j] = min large cam cần dùng để film đến i-th event, và dùng j smol cam
    dp[0][0] = 0;

    vector<ll> idxP(N + 1, 0), idxQ(N + 1, 0); // idx của cái event đầu tiên > i mà k được film tới, nếu mình đặt cam ở event i
    l(1, N + 1, i) {
        auto pos1 = upper_bound(vec.begin() + 1, vec.end(), vec[i] + W - 1); // giả sử W = 2, vec[i] = 7, thì cover được lên 8 th, chứ lên 9 quái đâu T_T
        idxP[i] = pos1 - vec.begin() - 1;

        auto pos2 = upper_bound(vec.begin() + 1, vec.end(), vec[i] + 2 * W - 1);
        idxQ[i] = pos2 - vec.begin() - 1;
    }

    l(0, N, i) {
        l(0, P + 1, j) {
            if (dp[i][j] <= Q) {
                if (j < P) dp[idxP[i + 1]][j + 1] = min(dp[idxP[i + 1]][j + 1], dp[i][j]); // dùng smol cam nên j+1
                dp[idxQ[i + 1]][j] = min(dp[idxQ[i + 1]][j], dp[i][j] + 1); // dùng cam to nên k cần j+1 ó
            } 
        }
    }

    ll ans = inf;
    l(0, P + 1, j) ans = min(ans, dp[N][j]);

    return ans;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    ll N, P, Q; cin >> N >> P >> Q; vector<ll> vec(N + 1, 0);
    //set<ll> st;
    l(1, N + 1, i) cin >> vec[i];
    sort(vec.begin() + 1, vec.end());

    if (N <= (P + Q)) {cout << 1; return 0;} // đặt mỗi event 1 cam riêng :D

    ll lo = 1, hi = 1e10, ans = -1;
    while (lo <= hi) {
        ll mid = (lo + hi) / 2;

        if (meow(N, mid, P, Q, vec) <= Q) {
            ans = mid;
            hi = mid - 1;
        }
        else lo = mid + 1;
    }

    cout << ans;
}

// Để ý bài này constraint N <= 2000, P <= 100 000, Q <= 100 000
// nên nhìn qua thì nếu tạo vector dp size (N * P) khả năng cao MLE (nếu dùng ll thì cf MLE lun)
// Cơ mà để ý là nếu P hoặc Q mà lớn hơn N phát thì mình cho W = 1 nlt vì mình có thể đặt mỗi chỗ 1 cam ^^

// So in short, mình chỉ cần động đến DP trong các TH P < N (ie. Pmax < 2000) 
// Hence, dp size max cũng tầm 4e6 th :D
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...