제출 #1208125

#제출 시각아이디문제언어결과실행 시간메모리
1208125gatapdevK개의 묶음 (IZhO14_blocks)C++20
0 / 100
0 ms328 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; const ll INF = LLONG_MAX/4; int n, K; vector<ll> a; vector<vector<ll>> stMax; vector<int> log2v; // Precompute sparse table for RMQ max void buildSparse() { log2v.assign(n+2, 0); for (int i = 2; i <= n; i++) log2v[i] = log2v[i/2] + 1; int maxLog = log2v[n]; stMax.assign(maxLog+1, vector<ll>(n+1)); for (int i = 1; i <= n; i++) stMax[0][i] = a[i]; for (int k = 1; k <= maxLog; k++) { for (int i = 1; i + (1<<k) - 1 <= n; i++) { stMax[k][i] = max(stMax[k-1][i], stMax[k-1][i + (1<<(k-1))]); } } } // Query max in a[l..r] ll queryMax(int l, int r) { if (l > r) return 0; int len = r - l + 1; int k = log2v[len]; return max(stMax[k][l], stMax[k][r - (1<<k) + 1]); } vector<ll> dp_prev, dp_cur; void compute(int k, int L, int R, int optL, int optR) { if (L > R) return; int mid = (L + R) >> 1; ll bestVal = INF; int bestPos = -1; int start = max(k-1, optL); int end = min(mid-1, optR); for (int j = start; j <= end; j++) { ll val = dp_prev[j] + queryMax(j+1, mid); if (val < bestVal) { bestVal = val; bestPos = j; } } dp_cur[mid] = bestVal; // Recurse on left and right compute(k, L, mid-1, optL, bestPos); compute(k, mid+1, R, bestPos, optR); } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cin >> n >> K; a.resize(n+1); for (int i = 1; i <= n; i++) cin >> a[i]; buildSparse(); dp_prev.assign(n+1, INF); dp_cur.assign(n+1, INF); dp_prev[0] = 0; // base k=1: prefix max for (int i = 1; i <= n; i++) dp_prev[i] = max(dp_prev[i-1], a[i]); // DP for k=2..K using divide-and-conquer optimization for (int k = 2; k <= K; k++) { compute(k, k, n, 0, n-1); dp_prev = dp_cur; } cout << dp_prev[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...