Submission #1229825

#TimeUsernameProblemLanguageResultExecution timeMemory
1229825kawaiiFeast (NOI19_feast)C++20
59 / 100
1096 ms9800 KiB
#include <iostream> #include <vector> #include <numeric> #include <algorithm> using namespace std; const long long INF = -1e18; // Use a sufficiently small negative number for initialization int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int n, k; cin >> n >> k; vector<long long> a(n); for (int i = 0; i < n; ++i) { cin >> a[i]; } // Compute prefix sums (0-based indexing for A, 1-based for prefix_sum) // prefix_sum[i] = sum of a[0]...a[i-1] vector<long long> prefix_sum(n + 1, 0); for (int i = 0; i < n; ++i) { prefix_sum[i + 1] = prefix_sum[i] + a[i]; } // dp[i] will store the maximum satisfaction using the first i plates (0..i-1) // with exactly j people (current iteration of j). vector<long long> prev_dp(n + 1, 0); // Base case: 0 people, max sat is 0 for any number of plates for (int j = 1; j <= k; ++j) { vector<long long> current_dp(n + 1, INF); current_dp[0] = 0; // 0 plates, j people assigned empty segments, max sat is 0. long long max_val = INF; // This will store max_{0 <= p < i} (prev_dp[p] - prefix_sum[p]) for (int i = 1; i <= n; ++i) { // When computing current_dp[i] (using plates 0..i-1) for j people: // Option 1: j-th segment ends before plate i-1 (or is empty at i-1). // Max satisfaction is current_dp[i-1]. current_dp[i] = current_dp[i - 1]; // Option 2: j-th segment ends exactly at plate i-1. // It starts at some plate p (0 <= p <= i-1). // Sum = a[p] + ... + a[i-1] = prefix_sum[i] - prefix_sum[p]. // Previous j-1 people used plates 0..p-1. Max sat is prev_dp[p]. // Total = prev_dp[p] + prefix_sum[i] - prefix_sum[p]. // We need max over 0 <= p <= i-1: max(prev_dp[p] - prefix_sum[p]) + prefix_sum[i]. // The term max(prev_dp[p] - prefix_sum[p]) needs to be calculated for p up to i-1. // The required max_val for index i is max_{0 <= p <= i-1} (prev_dp[p] - prefix_sum[p]). // This can be updated iteratively: max_{0 <= p <= i-1} = max(max_{0 <= p <= i-2}, prev_dp[i-1] - prefix_sum[i-1]) // Update max_val to include the term for index i-1: (prev_dp[i-1] - prefix_sum[i-1]) // This max_val will be used for calculating current_dp[i], maximizing over segments ending at i-1. max_val = max(max_val, prev_dp[i-1] - prefix_sum[i-1]); // If max_val was not INF, we can potentially end the j-th segment at i-1 if (max_val != INF) { current_dp[i] = max(current_dp[i], max_val + prefix_sum[i]); } } prev_dp = current_dp; } cout << prev_dp[n] << endl; 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...
#Verdict Execution timeMemoryGrader output
Fetching results...