Optimise a recurrence of the form
from to , when the optimal split point is monotone:
The algorithm
For a fixed layer , solve the range knowing lies in :
- Take the midpoint .
- Compute by scanning , recording the argmin .
- Recurse on with the range and on with .
vector<long long> prev_, cur;
void compute(int l, int r, int optL, int optR) {
if (l > r) return;
int m = (l + r) / 2;
pair<long long,int> best = {LLONG_MAX, -1};
for (int k = optL; k <= min(m, optR); k++)
best = min(best, {prev_[k] + C(k, m), k});
cur[m] = best.first;
int opt = best.second;
compute(l, m - 1, optL, opt);
compute(m + 1, r, opt, optR);
}
long long solve(int n, int layers) {
prev_ = baseLayer(n);
for (int i = 1; i <= layers; i++) {
cur.assign(n + 1, LLONG_MAX);
compute(0, n, 0, n);
swap(prev_, cur);
}
return prev_[n];
}Complexity: recursion levels, and at each level the scanned -ranges overlap only at their endpoints, totalling work. So per layer, overall.
When does monotonicity hold?
Sufficient condition: satisfies the quadrangle inequality (concave Monge)
Cost functions that satisfy it in practice:
- (sum of a range), or any convex function of a range sum
- number of inversions / pairs inside
- cost of grouping into one cluster with a central representative
- number of distinct values in
Verify before trusting
Brute-force the DP on small random inputs, record the argmins, and check they are non-decreasing. Thirty seconds of checking beats debugging a wrong answer. See Yao’s theorem for the formal conditions.
Computing efficiently
The recursion assumes is . When it is not, exploit the fact that consecutive evaluations move and by one — maintain the value with a two-pointer / Mo’s-style incremental structure:
int curL, curR; long long curCost;
long long C(int l, int r) {
while (curR < r) add(++curR);
while (curL > l) add(--curL);
while (curR > r) remove(curR--);
while (curL < l) remove(curL++);
return curCost;
}The amortized cost is total, matching the recursion — this combination is the standard solution to “partition an array into segments minimising the total number of equal pairs” style problems.
The optimisation family
| Recurrence | Requirement | Technique | Time |
|---|---|---|---|
| monotone opt | D&C DP | ||
| same, offline, totally monotone | Monge | SMAWK | |
| same, online | Monge | LARSCH | |
| QI + monotone | Knuth | ||
| lines | CHT | / | |
| fixed-width window | none | monotone queue | |
| ”exactly groups” with convex cost in | convexity | Aliens trick |
D&C DP vs Aliens trick
Both attack “partition into exactly parts”. D&C DP keeps the dimension and costs ; Aliens trick removes it, costing times the cost of one unconstrained solve. When is large (say ), Aliens is the only option. When is small, D&C DP is simpler and has no convexity requirement on the answer-vs- curve.
See also: Knuth Optimization · Aliens Trick · SMAWK