Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.
Let's first slightly change the problem to focus only on the pillars that support the bridge and not the other ones which should be destroyed. The overall cost consists of the cost due to differences in heights plus the cost of destroying unused pillars. The latter one is equal to the sum of all destruction cost minus the cost of those that are retained.
Dynamic programming. Consider a subproblem of building the bridges such that the last one ends on pillar
. Let
represent the minimum cost of solving this subproblem. The last bridge in the solution will span from some pillar
to
, which results in the formula:

A dynamic programming solution has to solve
subproblems, spending
time on each.
Two pillars. Can we do better if we know that the optimal solution consists only of two additional pillars besides the first and the last? If there's only one additional pillar, we can simply try them all. For the case of two additional pillars, we'll try all second pillars
and for each of them choose an optimal first pillar
.
The contribution of the first pillar to the overall cost is
. Let's ignore
for now (assume
). Intuitively, we would want to choose
close to the average of
and
. Calculating where derivative equals zero confirms our intuition. Therefore, we are interested in only two pillars — the largest among those smaller or equal to
and the smallest among those larger. As we try different pillars
from
to
, we can maintain a tree structure of pillars
ordered by their height. This allows us to find the two we need in
. For example, we can use the set
data structure from C++ for this purpose.
All that's left is to handle the term
. Their limited range of values is helpful in this case. We can maintain separate tree structures for every value of
and look for the optimal pillar
for every possible value of
. The time complexity is
,
.
Convex optimization. Let's rewrite the recursive definition from the dynamic programming solution.

Note that
is a constant term that depends only on
and is the same regardless of the choice of
. If the term
weren't present, we could simply maintain the best choice of
as we compute values of
for increasing
. Term
in the product complicates things. We can consider every pair
and
as a slope and
-intercept of a line. The problem of finding the best
reduces to finding the lowest line at
. To do this in
, we'll maintain a lower envelope of a set of lines. The data structure has to be dynamic — it should support insertion of a new line in
. Note that the lines comprising the lower envelope are ordered by their slope. Therefore, we can maintain a tree structure of these line segments. It allows us to quickly find the optimal line for a given
as well as insert a new one. We can abuse C++'s set
for this purpose. This optimization is often called the convex hull trick in relation to dynamic programming and solves the problem in
time.
Comments