Algorithms · Dynamic Programming

Monotone Decision Points: Divide-and-Conquer Optimization in DP

When the argmin of a one-dimensional recurrence is monotone in the state, the transition scan collapses from a factor of n to a logarithm, and the Monge condition is what licenses it.

A recurrence of the form

dp[i] = min over 0 <= j < i of ( dp[j] + C(j, i) )

with a state-dependent range for j has a naive cost of Θ(n²): n states, n candidates each. Many problems of this shape are solvable in Θ(n log n) or even Θ(n), because the optimal j for i is often a monotone function of i. The condition that guarantees monotonicity is a property of the cost C called the Monge condition, or the quadrangle inequality. It is a statement about the matrix of costs, and it is checkable independently of the algorithm.

The gain is large and the risk is asymmetric: a program that applies the optimization without proving the condition returns correct answers on the inputs that satisfy it and wrong ones otherwise, with no runtime signal. This article states the condition, derives the two standard algorithms from it, and covers the cases where it fails.

The Monge condition

Write the cost matrix M[j][i] = C(j, i) for j < i. The matrix is Monge if for all j_1 < j_2 and i_1 < i_2:

M[j_1][i_1] + M[j_2][i_2] <= M[j_1][i_2] + M[j_2][i_1]

Read informally: moving both indices in the same direction is cheaper than crossing them. Equivalently, the matrix has no “bad” 2×2 submatrix in which the diagonal from top-left to bottom-right is the more expensive one.

The consequence for the DP is the monotonicity of the argmin: for i_1 < i_2, opt[i_1] <= opt[i_2]. This monotonicity is established by the quadrangle inequality stated over rows of the matrix; the Monge inequality written above is its row-index form. The proof is the standard exchange: suppose opt[i_1] = j_2 > j_1 = opt[i_2]. Both choices are candidates for both states — the candidate ranges are nested, so j_1 is available at i_1 and j_2 at i_2 — and applying the inequality to the quadruple contradicts the assumed optimality of each. The argument needs the candidate ranges to be nested, which is why the monotonicity holds when j ranges over a prefix [0, i) and fails when the range is an arbitrary subset.

For interval DPs the analogous statement is Knuth’s condition, which bounds opt[lo][hi] between opt[lo][hi-1] and opt[lo+1][hi] and reduces the O(n³) table to O(n²). That derivation appears in interval DP and split enumeration. The one-dimensional form is the subject here.

Divide-and-conquer optimization

Given a monotone argmin, the candidates for a block of states can be bounded once the argmin at the block’s endpoints is known. The recursive algorithm uses exactly that.

To compute dp[i] for i in [lo, hi] given that opt[i] lies in [optLo, optHi], evaluate the midpoint mid, scanning all j in [optLo, min(optHi, mid-1)] to find opt[mid]. Then recurse on [lo, mid-1] with candidate range [optLo, opt[mid]] and on [mid+1, hi] with [opt[mid], optHi].

def solve(n, cost, prev):
    # cur[i] = min over j < i of prev[j] + cost(j, i), one layer at a time
    cur = [None] * n
    def rec(lo, hi, opt_lo, opt_hi):
        if lo > hi:
            return
        mid = (lo + hi) // 2
        best_val, best_j = None, -1
        for j in range(opt_lo, min(opt_hi, mid - 1) + 1):
            v = prev[j] + cost(j, mid)
            if best_val is None or v < best_val:
                best_val, best_j = v, j
        cur[mid] = best_val
        rec(lo, mid - 1, opt_lo, best_j)   # opt is non-decreasing, so it is bounded above
        rec(mid + 1, hi, best_j, opt_hi)   # ... and here bounded below
    rec(1, n - 1, 0, n - 2)
    return cur

The cost analysis is the part worth doing carefully. At each level of the recursion, the candidate ranges of the subproblems partition the parent’s range, so the total scan at a level is O(n). There are Θ(log n) levels, giving Θ(n log n). The claim “ranges partition” holds because the two children get [optLo, opt[mid]] and [opt[mid], optHi], which overlap at one element and otherwise split the parent range.

Two preconditions are easy to miss. Read and written values must come from different layers: the recurrence has no circular dependency, and the standard case is a layered DP where the table at layer k depends only on layer k-1. Writing results back into the array that is being read would let a half-finished layer feed itself, and the argmin monotonicity argument does not cover that. And the min(optHi, mid-1) clamp is necessary because j must be strictly less than i; without it the scan reads cost(j, j) or indexes past the end.

The recursion depth is Θ(log n), so unlike the memoized forms elsewhere in this cluster there is no stack problem even for n = 10^6.

Knuth’s optimization in one dimension

When the cost is a prefix-sum quantity — C(j, i) depends on the interval (j, i] and satisfies the quadrangle inequality — the argmin is not only monotone but bounded by its neighbours, and the bound can be applied directly inside the ordinary loop nest rather than through divide and conquer.

For the one-dimensional recurrence the bound reduces the scan per state to amortized constant work, so the whole table costs Θ(n²) instead of Θ(n³); the interval form described in interval DP and split enumeration gets the same reduction from O(n³) to Θ(n²). In both cases the saving is one factor of n, because the bound replaces a scan over all candidates with a scan over a window whose total width telescopes.

The condition that licenses the tighter bound is the quadrangle inequality over the cost — the same inequality that yields ordinary Monge monotonicity — together with monotonicity of C in both arguments and the requirement that the cost be additive over the interval, so that adding an element cannot decrease the cost of a containing interval. Knuth proved it for optimal binary search trees, and the bound between neighbouring entries follows from the same exchange argument applied twice.

The SMAWK route to linear time

For a totally monotone matrix — a slightly weaker condition than Monge that requires monotonicity only of the row minima of every submatrix — the row minima of all n rows can be found in O(n) time by the SMAWK algorithm, named for its five authors. The algorithm repeatedly reduces the number of columns by eliminating those that cannot contain a row minimum, using a comparison of adjacent columns, and recurses on the surviving columns at the even rows.

The reduction step is what gives the linear bound: when column c is compared with a later column at row r and column c loses, column c can be discarded for all rows below r by total monotonicity, and the symmetric comparison discards the later column for all rows above. Each comparison eliminates at least one column, and the surviving submatrix has at most half the rows, so the recurrence T(m, n) = O(m + n) + T(m/2, n) solves to O(m + n).

SMAWK applies to the DP only when the full cost matrix is available or computable in O(1) per entry. In many DP settings C(j, i) is a function call with nontrivial cost, and the constant in SMAWK’s O(n) comparisons is larger than the divide-and-conquer form’s. The practical choice between them is a constant-factor question, not an asymptotic one, and the divide-and-conquer version is the one usually implemented.

The Lagrange / aliens trick

A different class of optimization removes a dimension from the state by moving it into the objective. Suppose the DP is dp[i][k] — best value using exactly k segments among the first i elements — and the requirement is the best value for a specific k. The table is O(nk). If the cost function has the right convexity, adding a penalty λ per segment and computing the unconstrained optimum dp[i] for a single λ costs O(n), and the number of segments used is monotone decreasing in λ.

Binary search on λ therefore finds the value at which the optimal solution uses k segments, in O(n log(range)) total. The technique is exact when the value function is convex in k: at the breakpoint, the penalized optimum coincides with the constrained one, and the penalty can be subtracted. When it is not convex, the binary search converges to a point on the convex hull of the (k, value) pairs and returns a value that is achievable by a convex combination of two solutions rather than by an actual k-segment solution. That failure is silent and produces a plausible but unattainable number.

The convexity requirement is a property of the problem, and it is often established by an exchange argument showing that the marginal gain of an additional segment is non-increasing. Where the marginal gain can increase — for instance when segments have fixed setup costs that interact — the technique is invalid.

Verifying the condition before trusting the bound

The Monge inequality is a statement about all quadruples of indices, so a complete check is Θ(n⁴). Three practical alternatives exist.

Prove it analytically. Most costs that arise are sums over a range, and the inequality reduces to a statement about the per-element weights. For C(j, i) = P_i - P_j where P is a prefix sum, the inequality holds with equality. For C(j, i) = (P_i - P_j)², writing a = P_{j1}, b = P_{j2}, x = P_{i1}, y = P_{i2} makes the difference between the two sides 2(b - a)(x - y), which is at most zero whenever the prefix sums are non-decreasing — so the squared cost is Monge exactly when the underlying sequence is sorted.

Test on random small instances. Generate random cost matrices of size up to a few dozen and check the quadruple inequality exhaustively on the sampled values. This catches structural violations — a cost with an absolute value, a min, a non-monotone term — but not narrow violations that occur only at specific index combinations.

Compare against the quadratic DP. For each test input, run both the optimized and the naive version and compare the resulting tables. This is the strongest check and the only one that tests the implementation as well as the theory. It requires the quadratic version to exist, which is easy since the optimized version is derived from it, and it catches the clamp errors and off-by-one range bugs that the theory does not address.

What the optimizations have in common

Each technique here replaces a scan over candidates with a search over a smaller set justified by structure. Divide and conquer uses the monotonicity of the argmin to bound the candidate range per subproblem. Knuth’s bound uses the same monotonicity plus the neighbouring entries’ opt values. SMAWK uses total monotonicity to eliminate columns outright. The Lagrange trick replaces a constrained scan with an unconstrained one plus a binary search over a multiplier.

All four are valid only under a structural assumption about the cost, and all four fail by returning wrong values rather than by crashing or running slowly. That is the property that separates them from the optimizations in pseudo-polynomial knapsack, where the space reduction is unconditionally correct and only the time bound changes. An optimization that changes the answer when its precondition fails is a different kind of object, and it deserves a test that compares it against the unoptimized form on every input the program will accept.

References

  1. Geometric applications of a matrix-searching algorithm — Aggarwal, Klawe, Moran, Shor, Wilber; Algorithmica 2, 1987
  2. Optimum binary search trees — Donald Knuth, Acta Informatica 1, 1971
  3. Introduction to Algorithms, 4th edition — Chapter 14, Dynamic Programming — Cormen, Leiserson, Rivest, Stein; MIT Press