I am looking at the Codeforces problem A. Boredom:
Given a sequence consisting of integers. The player can make several steps. In a single step he can choose an element of the sequence (let's denote it ) and delete it, at that all elements equal to +1 and −1 must also be deleted from the sequence. That step brings points to the player.
I found the following code submitted by user Leeisateam:
input()
z = [0] * 7**6
for i in map(int, input().split()):
z[i] += i
a = b = 0
for i in z:
a, b = max(a, i + b), a
print(a)
I understand what this code is doing up until the final loop starts. We're creating a list z of the form
[0 X count_in_sequence(0), 1 X count_in_sequence(1), ..., n X count_in_sequence(n)].
After that b is assigned the value of a and a uses that (previous) value in the next iteration. I tried induction, but I still can't understand why this code would always work.
Some observations:
Now let's look at the code.
The code projects the values to their corresponding index, so that they are automatically visited in ascending order.
Then the variables
aandbare introduced. They represent two alternative solutions of picking values before the current valueiis taken (or not). The one represented byais one that might have taken the valuei-1, and so if that would be done, the valueiwould not be available anymore (as deleted by the previous pick). By consequence, we don't consider theascenario for pickingi. On the other handbrepresents a variant where we surely did not picki-1, and so we are sure that after scenariobwe can also pick valuei. So now after having consideredi, we have two scenarios:a(which wasn't extended) andb + i(note also thatihas all the duplicates summed up as we know we want to take all or nothing of it).In the next iteration of the loop, the role of
aandbchange, since nowbhas possibly selected that previousi, which now isi-1, and that previousbis nowa(it is like a swap).And so the loop "alternates" through the
zarray, keeping track of two possible scenarios.Describing this in words makes it quite verbose, but it does help to step through the code with a piece of paper using some limited inputs.
Example visualisation
Let's say we have input with the following (value, frequency) pairs:
Then we could visualise the values for
aandbas the loop makes iterations:zwill be equal to:irepresents what extra value can be added when we select the current value -- which is that value multiplied by its frequency in the input. This value is only allowed to be added tobas the scenario forahas allowed for the selection of the immediate predecessor value. Still, adding this valueitobis a potential new value fora, but only if it is better than whatais. In the example we see this isb+inot better thanawheniis 0 (which is true in the largest part of thezlist... having 76 entries).And at the end
ahas the solution: 296