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