CF - William and Robot

Author: Alex Du

Table of Contents

ExplanationImplementation

Explanation

First note that the only requirement for a valid solution is that for any even number knk \leq n, William must have selected at most k2\frac{k}{2} integers out of the first kk integers. It is impossible to select more than k2\frac{k}{2} integers in the first kk integers, since the robot will have taken all other k2\frac{k}{2} integers by the time you can choose your next integer. Note that it is also possible to "save" your choices, since you can choose less than k2\frac{k}{2} integers for k<nk < n, allowing you to choose more for a larger kk.

For example, if we had array of size 44, we could select either of the first two elements and either of the last two elements, selecting exactly k2\frac{k}{2} integers for both k=2k = 2 and k=4k = 4. Alternatively, we could select both of the last two elements, selecting 0 integers for k=2k = 2 and 22 integers for k=4k = 4. Note that we cannot take both the first and second element, since the Robot will take the one we don't pick.

To solve this problem, we can use a greedy algorithm.

For any even kk, if we know the k2\frac{k}{2} integers that make the highest sum, we can use this to find the k2+1\frac{k}{2}+1 integers for k+2k+2.

The base case is k=2k = 2, where the highest sum is simply the maximum of the first two integers.

Similarly, to gain the highest sum for our current kk, we will always select the maximum of the k1k-1 and k2k-2 elements, since we now have another turn and this will build directly off of our previous solution.

However, it is sometimes optimal to take both integers, rather than just the maximum of the two. After k=2k=2, we can choose to remove any previous integer we selected and replace it with the minimum of the two integers we are currently considering. Since we can remove any integer, we will remove the minimum. Therefore, this is only worth it if the minimum of the two integers is greater than the minimum of all the integers we already selected. To quickly access and remove the smallest integer, we can use either a priority queue or a multiset.

Implementation

Time Complexity: O(NlogN)\mathcal{O}(N \log N)

C++

#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> a(n);
for (int &i : a) { cin >> i; }

Join the USACO Forum!

Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!