For layered DPs (“split the array into segments”), if the optimal is nondecreasing in , compute one layer in by divide and conquer over with shrinking ranges of . Total . The sufficient condition is the quadrangle inequality on .
Quadrangle inequality (Monge)
satisfies the quadrangle inequality (QI) if for all :
| Cost of segment | QI (for minimisation) |
|---|---|
| range sum (any sign) | equality, both directions |
| convex function of a nonnegative range sum, e.g. | yes |
| number of equal pairs, number of inversions inside the segment | yes |
| (1D clustering) | yes |
| concave function of the range sum, number of distinct values, range max | reverse inequality (use them in maximisation) |
| (matrix chain) | no |
Reverse QI with maximisation is the mirror image and gives the same monotonicity.
Proof: QI implies monotone smallest argmin, and the examples
Let smallest optimum for and smallest optimum for , and suppose . QI with gives . Optimality of at gives where . Adding, : is optimal for too and smaller than , a contradiction.
Examples. With segments , , : for with the sums, . For pair counts, is the number of equal pairs (or inversions) with one element in and one in , . For a submodular measure such as the number of distinct values, , which is the reverse inequality.
Implementation
vector<ll> prv, cur;
template<class F> void solve(int l, int r, int optl, int optr, F C) { // fill cur[l..r]
if (l > r) return;
int m = (l + r) / 2, opt = optl; ll best = LLONG_MAX;
for (int k = optl; k <= min(m - 1, optr); k++) { // k < m: last segment [k, m) nonempty
if (prv[k] == LLONG_MAX) continue;
ll v = prv[k] + C(k, m);
if (v < best) best = v, opt = k;
}
cur[m] = best;
solve(l, m - 1, optl, opt, C); solve(m + 1, r, opt, optr, C);
}
// layers: prv[0] = 0, others INF; for t in 1..T: cur.assign(n + 1, INF); solve(1, n, 0, n - 1, C); swap(prv, cur);Proof: per layer
The recursion on halves the range of , so it has levels. On one level, the subproblems’ -ranges are consecutive and overlap only at endpoints (each split passes to both sides), so the total length scanned on a level is . Hence per layer, assuming is .
Costs that are not
If is maintained incrementally (pairs of equal values, distinct counts), keep a Mo-style window and move its ends to on each evaluation. Within one layer the window moves times in total, because along the recursion the evaluations of a subproblem form a contiguous sweep of and the jumps between subproblems are bounded by the subproblem sizes. CF 868F “Yet Another Minimization Problem” (cost = equal pairs) is the standard example.
int L = 0, R = 0; ll window = 0; // window [L, R), cnt[] of values
auto C = [&](int l, int r) {
while (R < r) window += cnt[a[R++]]++;
while (L > l) window += cnt[a[--L]]++;
while (R > r) window -= --cnt[a[--R]];
while (L < l) window -= --cnt[a[L++]];
return window;
};Related tools
| Shape | Tool | Cost |
|---|---|---|
| layered, Monge, offline | D&C (this note), or SMAWK per layer | / |
| single layer, online ( depends on of the same layer) | binary-search queue / LARSCH (1D1D) | / |
| many layers, answer convex in | Aliens trick removes the layer dimension (Aliens) | |
| interval DP | Knuth–Yao (Knuth) | |
| (linear in a per-transition slope/intercept) | convex hull trick (CHT) | / |
| fixed-width window, no Monge structure needed at all | monotonic queue (Monotonic Queue) |
Monotonicity of the argmin is also often checkable empirically: run the DP on random small inputs and assert that the smallest argmins are nondecreasing.
D&C optimization vs the Aliens trick, when both apply (“partition into exactly parts” with a convex cost): D&C keeps the layer dimension and costs ; Aliens removes it entirely, costing regardless of . When is large (say ), Aliens is the only practical option. When is small, D&C is simpler to implement and needs no convexity assumption on the answer-vs- curve — only the per-layer quadrangle inequality.