PROBLEM LINK:
Practice
Contest: Division 1
Contest: Division 2
Contest: Division 3
Contest: Division 4
Author: raysh07 and iceknight1093
Tester: sushil2006
Editorialist: iceknight1093
DIFFICULTY:
Easy
PREREQUISITES:
Sorting
PROBLEM:
You have an array A of length N and an K coins.
Consider the following process:
- Start with \text{score} = 0 and x = 0.
- For each i from 1 to N, in order, you can:
- Pay zero coins and do nothing.
- Pay one coin (if you have it) to increase \text{score} by A_i and x by 1.
- Pay two coins (if you have them) to increase \text{score} by A_i+x and x by 1.
For each K from 1 to 2N, find the maximum possible value of \text{score}.
Here, N \leq 2000.
EXPLANATION:
In the easy version of the problem, N \leq 2000 which means \mathcal{O}(N^2) or so is an acceptable complexity.
This means we can for example try to solve for a fixed value of K in linear (or close to linear) time and it’ll be fast enough - so let’s do exactly that.
Let’s call an operation where we pay one coin (and increase the score only by A_i) a type 1 operation, and an operation where we pay two coins (to increase the score by A_i + x) a type 2 operation.
Suppose we choose to perform c_1 operations of type 1, and c_2 operations of type 2.
How should we perform them?
First off, we surely need c_1 + 2c_2 \leq K, since the left side is the total number of coins spent.
If this doesn’t hold we can’t perform any combination of c_1 and c_2 moves, so we can ignore such cases entirely.
Now, we’ll perform c_1 + c_2 operations that increase our score in total.
Each type 1 operation increases \text{score} by the corresponding A_i, while each type 2 operation increases \text{score} by the corresponding A_i as well as by x.
Further, x increases by 1 each time we perform a type 1 or a type 2 operation.
So, it can be seen that:
- If we fix the set of (c_1 + c_2) elements we’re adding to the score, it’s then optimal to perform the c_2 operations of type 2 at the very end.
This will allow the value of x to increase as much as possible before we start adding it to the score.
Specifically, since we start adding x to the score after the first c_1 moves, the contribution of x to the score will be exactly
c_1 + (c_1 + 1) + \ldots + (c_1 + c_2 - 1). - From above, we see that the contribution to the score of x is totally independent of which c_1 + c_2 elements were chosen.
So, we might as well just choose the largest c_1 + c_2 elements to add to the score.
The above analysis immediately gives us a solution in \mathcal{O}(N^2) for a fixed value of K.
Fix the values of c_1 and c_2, then the answer is just the sum of the largest c_1 + c_2 elements of A, plus c_1 + (c_1 + 1) + \ldots + (c_1 + c_2 - 1).
Running this for each K is too slow, so we need to optimize it further.
Instead of fixing the values of c_1 and c_2 separately, let’s fix the value of c_1 + c_2 instead.
Let S now denote the sum of the largest c_1 + c_2 elements of A (which can be found in constant time by sorting A and building its prefix sums).
Observe that if we fix the value of c_1, the final score will now be S + c_1 + (c_1 + 1) + \ldots + (c_1 + c_2 - 1).
Clearly, it’s best if c_1 is as small as possible to maximize this quantity.
Equivalently, we want c_2 to be as large as possible.
Now, recall that we have another constraint: a pair of (c_1, c_2) is only valid if c_1 + 2c_2 \leq K.
This tells us that c_2 \leq K - (c_1 + c_2).
Of course, we must also have c_2 \leq c_1 + c_2 itself, since c_1 cannot be negative.
Since we’ve already fixed both K and the sum (c_1 + c_2), we already know the maximum allowed value of c_2 - it’s exactly \min(c_1 + c_2, K - (c_1 + c_2)).
So, we can just use this value of c_2 to then compute c_1, and hence the sum S + c_1 + (c_1 + 1) + \ldots + (c_1 + c_2 - 1).
We’re now only iterating through all the values of (c_1 + c_2) from 0 to K, and solving for each one in constant time.
This gives us a solution for a fixed value of K in \mathcal{O}(N), which is exactly what we wanted.
To summarize, when solving for a fixed value of K:
- Fix the value of c_1 + c_2, say i.
i varies from 0 to K. - Let S_i denote the sum of the largest i elements of A.
This can be found in constant time using prefix sums. - Compute c_2 = \min(i, K - i), and then c_1 = i - c_2.
- The best possible score for this fixed i is then S_i + c_1 + (c_1 + 1) + \ldots + (c_1 + c_2 - 1).
S_i is already known, and the remaining part is just the sum of several consecutive numbers and so can be computed easily. - The answer for K is the maximum score across all i.
TIME COMPLEXITY:
\mathcal{O}(N^2) per testcase.
CODE:
Editorialist's code (PyPy3)
for _ in range(int(input())):
n = int(input())
a = list(map(int, input().split()))
s = [0]
for x in reversed(sorted(a)):
s.append(s[-1] + x)
ans = [0]*(2*n + 1)
for k in range(1, 2*n+1):
for i in range(min(n, k)+1):
c2 = min(i, k-i)
c1 = i - c2
ans[k] = max(ans[k], s[i] + c1*c2 + c2*(c2-1)//2)
print(*ans[1:])