Submission #1208138

#TimeUsernameProblemLanguageResultExecution timeMemory
1208138gatapdevK blocks (IZhO14_blocks)C++20
0 / 100
0 ms328 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = (ll)1e18;

int n, K;
vector<ll> a;
vector<vector<ll>> dp;
vector<vector<ll>> st;    // sparse table for range-max
vector<int> logTable;

// Xây sparse table ð? query max trên a[1..n] trong O(1)
void buildSparseTable() {
    int maxLog = floor(log2(n)) + 1;
    st.assign(maxLog, vector<ll>(n+1));
    logTable.assign(n+1, 0);
    for(int i = 2; i <= n; i++)
        logTable[i] = logTable[i/2] + 1;
    // c?p ð? 0
    for(int i = 1; i <= n; i++)
        st[0][i] = a[i];
    // c?p ð? k
    for(int k = 1; k < maxLog; k++) {
        int len = 1 << k;
        for(int i = 1; i + len - 1 <= n; i++) {
            st[k][i] = max(st[k-1][i],
                           st[k-1][i + (len>>1)]);
        }
    }
}
// l?y max trên a[l..r]
inline ll getMax(int l, int r) {
    int len = r - l + 1;
    int k = logTable[len];
    return max(st[k][l], st[k][r - (1<<k) + 1]);
}

// Compute dp[k][i] for i in [L..R], knowing optimal split j ? [optL..optR]
void compute_dc(int k, int L, int R, int optL, int optR) {
    if (L > R) return;
    int mid = (L + R) >> 1;
    // t?m j t?t nh?t trong [optL .. min(mid-1, optR)]
    ll bestCost = INF;
    int bestJ = optL;
    int upper = min(mid-1, optR);
    for(int j = optL; j <= upper; j++) {
        // chia sau j => ðo?n m?i là a[j+1..mid]
        ll cost = dp[k-1][j] + getMax(j+1, mid);
        if (cost < bestCost) {
            bestCost = cost;
            bestJ = j;
        }
    }
    dp[k][mid] = bestCost;
    // ð? quy 2 n?a v?i gi?i h?n opt
    compute_dc(k, L, mid-1, optL, bestJ);
    compute_dc(k, mid+1, R, bestJ, optR);
}

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

    cin >> n >> K;
    a.assign(n+1, 0);
    for(int i = 1; i <= n; i++)
        cin >> a[i];

    buildSparseTable();

    // kh?i dp: dp[k][i] = INF
    dp.assign(K+1, vector<ll>(n+1, INF));
    // v?i k=1: ch? 1 ðo?n, dp[1][i] = max(a[1..i])
    for(int i = 1; i <= n; i++)
        dp[1][i] = getMax(1, i);

    // tính k = 2..K
    for(int k = 2; k <= K; k++) {
        // v?i m?i k, j ph?i >= k-1 ð? có ð? k-1 ðo?n cho prefix
        compute_dc(k, 1, n, k-1, n-1);
    }

    cout << dp[K][n] << "\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...