Editorial for Baltic OI '07 P2 - Sorting
Submitting an official solution before solving the problem yourself is a bannable offence.
Important observations
When looking at the description of what happens when moving a player, we can see that if we move a player towards the front of the list, the moving cost of some other players increases, whereas if we move a player towards the end of the list, the moving cost of some other players decreases. So, it might be helpful to move players first which have to be moved towards the end of the list to decrease the moving costs of future moves. This observation may lead to the following two ideas:
- Each player is moved at most once.
- The players who are moved are moved in ascending order according to their score.
A proof that these two ideas are correct will follow later.
Brute force solution
Using the two ideas mentioned above, a brute force solution would try all
selections of players to be moved, and then move them to their required position
in ascending order according to their score. The complexity of this solution
would be .
Dynamic programming solution
Let the players be numbered from to
according to their final position in
the ranklist. With dynamic programming, we want to determine the minimum
cost to get the players
in their correct relative order with the first of these
players at original position
. It is tricky to determine the current position of
the next player to be moved. It would be far easier if we knew that all players
already moved towards the end of the list; in that case, in order to
determine the current position of player
, we could count how many players
with bigger scores exist which have an original index position smaller than
player
. Obviously, if some of the players with the
smallest scores didn't
move, the current position for player
determined by this method can be too
small.
However, if we assign a moving cost to each player who doesn't move, we
can take care of the underestimated moving cost for players with bigger score.
Let's see what happens if we didn't move player . This means that players
with bigger score will be moved before him, so when determining the position
of a player
which appears after player
in the list, the determined rank would
be too small by
. So the moving cost for a player who doesn't move is
the sum of
for all players
which appear between player
and the
position of player
.
It is possible to implement a dynamic programming solution using this idea
with complexity . With dynamic programming,
we can determine the minimal overall moving costs and which players were
moved. Now, we simply need the second part of the brute force solution to
generate the actual moves performed.
Proof
Here is the proof of why the two ideas mentioned above are correct:
Let's look at the player with the smallest score, who has to end up at
position
.
Claim 1: If is moved at all, it is optimal to move him directly to the
end of the list.
Proof: Obviously, moving him towards the front will only increase the costs
of other players to be moved. So assume he will be moved towards the end
to a position (thus saving
steps). Now there are two possibilities:
either, the
players after him in the list have to be moved and their costs
are increased by
(as opposed to that
was moved to the end), or
has to be moved again, which clearly is not optimal.
Claim 2: If is moved at all, we can do this in the first move.
Proof: Following from Claim 1, we already know the second part of the
moving costs is fixed. So the only reason not to move first is that his
current position decreases caused by moving other players. But these players
have their moving costs increased by
because
wasn't moved to the end.
If is moved, we have reduced our problem to the same problem with
players. If
is not moved, we have a similar problem with
players with the additional restriction that all players after
have to be
moved before
.
Let be the player with the smallest score among the remaining
players. We can see that it does not help to move
after
, because that
would mean we have to move him again, and we gain nothing from moving
him past other players still to be moved (for each of them, we decreased the
moving cost by
, and increased the moving cost of
by at least one). If
is currently placed before
in the list, by similar arguments as for
Claim 1 we can argue that if
is moved at all, it is optimal to move him
directly before
. Also, Claim 2 still works. So we are left with the case
that
is currently placed after
and has to be moved towards the front.
If there are players between
and
, we could consider moving them
first. If we move
first, the start positions of the players in between are
increased by
. But if we move some player in between first, the end position
where
has to be moved to increases by
, so it can't be bad if we move
first.
So, we can see that by using induction and the arguments presented above we can prove that each player is moved at most once, and the players can be moved in ascending order according to their score.
Comments