/**
* Covered Walkway
* @author vanb
*
* This problem would be pretty easy, if it weren't for the size of the data sets.
* If the data sets were small, a simple DP solution would suffice:
*
* Let best[i] be the best you can do covering A[0]..A[i].
* Then best[i] = MIN{best[j] + C + (A[i]-A[j+1])^2} for j<i
* and best[n-1] is your solution.
*
* The simple solution would be to implement two loops:
* for( int i=0; i<n; i++ ) to compute each best[i],
* and for( int j=0; j<i; j++ ) to find that minimum.
* But, that would be O(n^2), and when n can be as large as a million,
* that's too much.
*
* This solution will use that basic concept, but we'll find a more efficient way
* of finding that minimum.
*
* Suppose we're at A[i], and we're trying to choose whether it's best to break
* at A[j] or A[k] (j<k<i). Note that since the input is guaranteed to be in
* increasing order, A[j]<A[k]<A[i]. So, we've got to compare:
* best[j] + C + (A[i]-A[j+1])^2 to best[k] + C + (A[i]-A[k+1])^2
* best[j] + C + A[i]^2 - 2*A[i]*A[j+1] + A[j+1]^2 to best[k] + C + A[i]^2 - 2*A[i]*A[k+1] + A[k+1]^2
*
* Since C and A[i] will be the same for any j & k, then we're comparing
* best[j] - 2*A[i]*A[j+1] + A[j+1]^2 to best[k] - 2*A[i]*A[k+1] + A[k+1]^2.
*
* If we look at this as a function of A[i] (in fact, let x=A[i]), it looks like this:
* -2*a[j+1]*x + (best[j]+a[j+1]^2) compared to -2*a[k+1]*x + (best[k]+a[k+1]^2)
*
* So, for any A[i], if we want to know if splitting between A[j] and A[j+1] is better
* than splitting between A[k] and A[k+1], then all we have to do is plug A[i] in
* for x in this linear equation, and see which is smaller (since smaller is better).
*
* But, since these are linear, we can take some shortcuts. Think of them as lines,
* in y=mx+b form, with m(j)=-2*A[j+1], and b(j)=(best[j]+a[j+1]^2). Look at that slope (m(j)).
* As j increases, so does A[j+1], and so that slope becomes more intensely negative.
* That means that, if j<k, once k becomes a better breakpoint, j will never be better again.
* That is, if j<k and m(k)*x+b(k) < m(j)*x+b(j) for some x,
* then m(k)*w+b(k) < m(j)*w+b(j) for all w>x.
* Once k becomes better, we never have to look at j again.
*
* We'll maintain a linked list of breakpoints, and remember their m's and b's.
* We'll walk forward through this list, and never have to go back. Any new
* breakpoint we add will have the most negative slope, so it will need to be
* added to the end of the list. But, it may shunt off some other breakpoints.
* So, we'll add it to the end of the list and remove any breakpoints that it
* shunts off. If we do that, then we won't have to go through the whole list to find
* the minimum. Every breakpoint will either get walked over once, or shunted off once.
* Either way, we've reduced that process of finding the minimum to O(n) prorated
* over the entire algorithm, making the whole thing O(n).
*
*/
4258 | Covered Walkway |