Editorial for IOI '09 P8 - Salesman
Submitting an official solution before solving the problem yourself is a bannable offence.
We'll start by considering only the case where no two fairs occur on the same day. Later we'll show how to modify our algorithm to incorporate fairs that occur on the same day.
The first polynomial solution
First we'll describe a fairly standard dynamic programming algorithm. We order the fairs according to the day when they take place. For each fair
To avoid special cases, we'll add dummy fairs
The values
Let
We can then write:
(Explanation: To compute
The time complexity of this algorithm is
An improved solution
We will now improve the previous algorithm. Note that the profit
We can divide the fairs
Consider locating the optimal previous fair upstream of
We will now show a relatively simple data structure that will allow us to locate the optimal previous fair upstream of fair
The data structure is commonly known as an interval tree. We can assign the fairs new labels according to their unique positions on the river. More precisely, let
Our interval tree is a complete binary tree with
Leaves in this binary tree correspond to the fairs, and the order in which fairs are assigned to leaves is given by the values
Now note that each node in our tree corresponds to an interval of fairs — hence the name "interval tree". In each node of the interval tree, we will store the answer to the following question: "Let
Given this information, we can easily determine the optimal choice for the next fair
In our solution we will, of course, have two interval trees: one for the direction upstream and one for the direction downstream. For each fair
Hence we process each fair in
Another equally good solution
In this section, we will show another solution with the same complexity, which uses an "ordered set" data structure only, and can easily be implemented in C++ using the set
class.
As before, we will process the fairs one by one, ordered by the day on which they occur. Imagine a situation after we have processed some fairs. Let
In human words,
Once fair
On the other hand, if a fair is currently not covered by any other fair, there are some locations on the river for which
In our solution, we will maintain the set of currently active fairs, ordered by their position on the river. We will use an "ordered set" data structure, most commonly implemented as a balanced binary tree.
It can easily be shown that for each active fair
Hence whenever we are going to process a new fair
After we process the fair
In this solution, each fair is inserted into the set of active fairs once, and is erased from the set at most once. In addition, when processing each fair we make one query to find the closest two active fairs. Each of these operations takes
Multiple fairs on the same day
First of all, note that we cannot process fairs that are on the same day one by one — because we must allow the salesman to visit them in a different order than the one we picked.
There may be many ways in which to visit the fairs on a given day. However, we don't need to consider all of them, just some subset that surely contains the optimal solution.
Suppose that we already picked some order in which to visit the fairs on a given day. Let
We will process each day in two phases. In the first phase, we process each fair
In the second phase, we will take travelling upstream or downstream into account. We will consider each direction separately. When processing a direction, we'll process the fairs in order, and for each of them we'll determine whether it is more profitable to start at this fair (i.e., use the value computed in the previous step) or to start sooner (i.e., use the optimal value computed for the previous fair in this step, subtract the cost of travel from that fair to this one, and add the profit from this fair).
For each fair
(DMOJ curator's note: I'm not sure which sections the following paragraph is referring to)
Finally, we need to update the set of active fairs. When using an interval tree data structure as in Section , this is accomplished simply by adding each fair to the upstream and downstream interval trees. When using an ordered set as in Section , one must take a little more care, as not all of the fairs that we have just processed will be active. This is easily catered for by modifying our update process — before inserting a new active fair, we check that the fair is actually active by examining its potential neighbours in the data structure. If either of the neighbouring fairs covers the one being added, then it is not active, and so should not be added to the active fairs set. With this modification, we can update the entire data structure by sequentially attempting to add each fair (in any order).
Clearly, the additional time needed to process the second phase on any day is linear in the number of fairs that day, assuming we already have them sorted according to their location (which is easily accomplished by adding this as a tiebreaker to the comparison function used to sort all fairs in the beginning). Furthermore, the update steps for the interval tree and ordered set both take
Comments