제출 #1344448

#제출 시각아이디문제언어결과실행 시간메모리
1344448MisterReaperSki 2 (JOI24_ski2)C++20
100 / 100
648 ms486196 KiB
#include <bits/stdc++.h>

using i64 = long long;
using i128 = __int128_t;

#ifdef DEBUG 
    #include "/home/ahmetalp/Desktop/Workplace/debug.h"
#else
    #define debug(...) void(23)
#endif

template<typename T>
bool chmin(T& a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}

constexpr int max_N = 300 + 5;
constexpr i64 inf = i64(1E18);

int N;
i64 K;
int H[max_N];
int C[max_N];

int M;
int cnt[2 * max_N];
int mn[2 * max_N];
bool vis[2 * max_N][max_N][max_N];
i64 dp[2 * max_N][max_N][max_N];

i64 cost(int x, int t) {
    i64 y = 1LL * x * t;
    if (y >= (inf + K - 1) / K) {
        return inf;
    }
    return y * K;
}

// std::pair<int, i64> g(int x, int y, int t1, int t2) {
//     if (x <= 0) {
//         return {0, 0};
//     }
//     i64 res = 0;
//     int t = t2 - t1;
//     for (int i = 0; i < t && x; ++i) {
//         int take = std::min(x, y);
//         x -= take;
//         res += take * i;
//     }
//     res += t * x;
//     return {x, res * K};
// }

std::pair<int, i64> g(int x, int y, int t1, int t2) {
    if (x == 0) {
        return {0, 0};
    }
    int t = t2 - t1;
    int n = (x + y - 1) / y;
    assert(n >= 1);
    if (n <= t) {
        int lst = x - (n - 1) * y;
        i64 c = 1LL * y * (n - 1) * (n - 2) / 2 + 1LL * lst * (n - 1);
        return {0, c * K};
    } else {
        i64 c = 1LL * y * t * (t - 1) / 2;
        c += 1LL * (x - y * t) * t;
        return {x - y * t, c * K};
    }
}

std::vector<int> all;
i64 f(int h, int a, int b) {
    if (h == M) {
        if (b != 0) {
            return inf;
        }
        return 0;
    }
    if (vis[h][a][b]) {
        return dp[h][a][b];
    }
    vis[h][a][b] = true;
    i64& res = dp[h][a][b] = inf;
    if (a == 0) {
        chmin(res, f(h + 1, a, b + cnt[h]) + cost(b + cnt[h], all[h + 1] - all[h]));
        if (mn[h]) {
            auto[nb, c] = g(b + cnt[h], 1, all[h], all[h + 1]);
            chmin(res, f(h + 1, 1, nb) + c);
        }
    } else {
        if (a != N) {
            chmin(res, f(h, a + 1, b) + C[mn[h - 1]]);
        }
        auto[nb, c] = g(b + cnt[h], a, all[h], all[h + 1]);
        debug(b + cnt[h], a, all[h], all[h + 1], nb, c);
        chmin(res, f(h + 1, a, nb) + c);
    }
    debug(h, a, b, res);
    return res;
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    std::cin >> N >> K;

    for (int i = 1; i <= N; ++i) {
        std::cin >> H[i] >> C[i];
    }

    for (int i = 1; i <= N; ++i) {
        all.emplace_back(H[i]);
        all.emplace_back(H[i] + 1);
    }

    std::sort(all.begin(), all.end());
    all.erase(std::unique(all.begin(), all.end()), all.end());

    M = int(all.size());
    all.emplace_back(all.back() + N + 5);

    for (int i = 1; i <= N; ++i) {
        int p = int(std::lower_bound(all.begin(), all.end(), H[i]) - all.begin());
        cnt[p] += 1;
        if (mn[p] == 0 || C[mn[p]] > C[i]) {
            mn[p] = i;
        }
    }

    for (int i = 1; i < M; ++i) {
        if (mn[i] == 0 || C[mn[i]] > C[mn[i - 1]]) {
            mn[i] = mn[i - 1];
        }
    }

    i64 ans = f(0, 0, 0);

    std::cout << ans << '\n';

    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...