Editorial for COCI '06 Contest 3 #6 Lista
Submitting an official solution before solving the problem yourself is a bannable offence.
There are three parts to the solution.
The first part requires us to simulate Mirko's moves. As suggested by the problem statement, a doubly-linked list is to be used, supporting three operations ("erase", "insert before" and "insert after").
The second part requires us to find the smallest set of nodes to be moved to bring the list back to its starting state. Note that this is equivalent to finding the largest set of nodes that will not be moved, or the longest increasing subsequence (not necessarily contiguous). The longest increasing subsequence is found as follows.
Let be the smallest number that can end an increasing subsequence of length . is then a (not necessarily strictly) increasing sequence – if an increasing subsequence of length can end in , then so can a subsequence of length .
Let and to start with. Iterate the list left to right, and for each number :
The number can extend any subsequence ending in a number less than . We use binary search to find the largest so that . Appending to that subsequence, the length becomes , so we set .
The length of the longest increasing subsequence is the largest for which is finite. The solution is then .
In the third part we find the sequence of moves that restores the list's original state. Extract the numbers that form the longest increasing subsequence into a separate sequence (sorted in increasing order). The following algorithm generates the desired sequence of moves:
for each number x from 1 to N not in A
let y be the smallest number in A such that y > x
if there is no such y then
move x to the end of the list
else
move x in front of y
Comments