Submission #59732

#TimeUsernameProblemLanguageResultExecution timeMemory
59732model_codeHomecoming (BOI18_homecoming)C++17
44 / 100
270 ms110468 KiB
// Andrei-Costin Constantinescu // O(N * K) - Dynamic Programming #include <bits/stdc++.h> #include "homecoming.h" using namespace std; const int NMAX = 2000000; const int VALMAX = 1000000000; void subtaskAsserts(int N, int K, int a[], int b[]) { assert(1LL * N * K <= NMAX); } typedef long long int lint; void asserts(int N, int K, int a[], int b[]) { assert(1 <= K && K <= N && N <= NMAX); for (int i = 0; i < N; ++ i) { assert(0 <= a[i] && a[i] <= VALMAX); assert(0 <= b[i] && b[i] <= VALMAX); } } int A[2 * NMAX + 5], B[2 * NMAX + 5]; lint dpTaken[2 * NMAX + 5]; lint dp[2 * NMAX + 5]; lint sPartB[2 * NMAX]; inline lint getSPartB(int l, int r) { lint sum = sPartB[r]; if (l > 0) sum -= sPartB[l - 1]; return sum; } lint solve(int N, int K, int a[], int b[]) { asserts(N, K, a, b), subtaskAsserts(N, K, a, b); // Copy and double a, b for internal use for (int i = 0; i < N; ++ i) { A[i] = a[i], A[N + i] = a[i]; B[i] = b[i], B[N + i] = b[i]; } // Compute the partial sums of B sPartB[0] = B[0]; for (int i = 1; i < 2 * N; ++ i) sPartB[i] = sPartB[i - 1] + B[i]; lint ans = 0; const auto f = [&](const int i) { dp[i + N] = 0; for (int j = i + N - 1; j >= i + 1; -- j) { if (j + K - 1 < i + N) { dpTaken[j] = dp[j + K]; if (j + K < i + N) dpTaken[j] = max(dpTaken[j], dpTaken[j + 1] + A[j + 1] - B[j + K]); } dp[j] = dp[j + 1]; if (j + K - 1 < i + N) dp[j] = max(dp[j], dpTaken[j] + A[j] - getSPartB(j, min(j + K - 1, i + N - 1))); } ans = max(ans, dp[i + 1]); }; const auto g = [&](const int where_0) { dp[where_0 + N] = dpTaken[where_0 + N] = 0; for (int j = where_0 + N - 1; j >= where_0; -- j) { if (j + K - 1 > where_0 + N - 1) { if (j + 1 < where_0 + N) dpTaken[j] = dpTaken[j + 1] + A[j + 1]; else dpTaken[j] = dpTaken[j + 1]; } else if (j + 1 <= where_0 + N - 1) { if (j + K <= where_0 + N - 1) dpTaken[j] = max(dp[j + K], dpTaken[j + 1] + A[j + 1] - B[j + K]); else dpTaken[j] = max(dp[j + K], dpTaken[j + 1] + A[j + 1]); } else dpTaken[j] = max(dp[j + K], dpTaken[j + 1]); dp[j] = max(dp[j + 1], dpTaken[j] + A[j] - getSPartB(j, min(j + K - 1, where_0 + N - 1))); } ans = max(ans, dpTaken[where_0] + A[where_0] - getSPartB(where_0, where_0 + K - 1)); }; // Fix a textbook we'll NOT take (out of the first K) for (int i = 0; i < K; ++ i) f(i); // Now, assume we take the first K textbooks for sure g(0); return ans; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...