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