UVa 10020 - Minimal coverage

10020 - Minimal coverage

 * http://acm.uva.es/p/v100/10020.html

Summary
A little bit of thinking will lead to a nice Greedy solution.

Explanation
We are given $$n <= 100000$$ line segments with integer coordinates. We are also given an integer m. We want to find the minimal number of line segments needed to cover $$[0, m]$$.

Sort the line segments by the left end increasing, and then break ties by the right end decreasing. So in our ordering, $$[-1, 5] < [-1, 2] < [1, 6]$$. Then iterate through the segments, keeping track of two numbers, the left end, and the right end. The left end starts at 0, and keeps track of where segments must start before. The right end stores the furthest point at which any segment which is at least partially left of left end can reach. When we hit a segment which is not left of the left end, we know that we must take a segment in order to cover the left end. We greedily take the segment corresponding to right end, and then make right end the new left end. We can get no benefit from taking a segment that ends earlier then the furthest right end we computed, which justifies the greedy heuristic.

Optimizations
To optimize dense inputs, we can avoid the sort by keeping an array A. $$A_i$$ stores the longest segment with the left end exactly i. For negative numbers, we simply store the maximum right end at $$A_0$$. For indicies with no corresponding segment, we simply store the right end to be equal to the index. Then we can perform the same scan.

Input
7

1 -1 0 -5 -3 2 5 0 0

1 -1 0 0 1 0 0

10 -2 5 -1 6 -1 3 0 4 1 5 2 6 3 7 7 8 8 10 8 9 0 0

10 -2 5 -1 6 -1 3 0 4 1 5 2 6 3 7 8 10 8 9 0 0

10 2 5 5 3 2 3 2 5 0 0

10 0 10 0 10 0 0

6 0 2 2 4 4 6 6 8 0 0

Output
0

1 0 1

4 -1 6 3 7 7 8 8 10

0

0

1 0 10

3 0 2 2 4 4 6