Quadrangle-inequality optimization exploits decision monotonicity in a state transition and is also commonly called decision-monotonicity-optimized DP.
Basic knowledge
Consider the simplest case, in which we need to solve the following series of optimization problems:
Assume that the cost function can be computed in time.
Convention
A dynamic-programming state transition can often be written as a series of optimization problems. Taking (1) as an example, these problems have a parameter , and both the objective function and the feasible region may depend on . For each problem, after the parameter is fixed, choose a feasible solution to minimize the value of the objective function. For convenience, an optimization problem with parameter will be called “problem ” below; its feasible solution is called “decision ”, and the value attained by the objective function at the optimal solution is called “state ”. We also denote the smallest optimal decision point for problem by .
In general, the total time complexity of these problems is , because for problem we must consider every possible decision . When decision monotonicity holds, the decision space can be narrowed effectively, improving the total complexity.
- Decision monotonicity: for any , we have .
Note
For a problem , the set of optimal decisions need not be an interval. Decision monotonicity can in fact be defined on sets of optimal decisions. For sets and , define if and only if for every and , we have and . This implies the monotonicity of the smallest (and largest) optimal decision point, which is the definition used here. The conclusions below stated for the smallest optimal decision point also apply to the largest optimal decision point. However, it is possible for the smallest optimal decision of a larger problem to be strictly smaller than the largest optimal decision of a smaller problem; that is, for some , we may have . Therefore, code should always ensure that it computes either the smallest or the largest optimal decision point consistently.
On the other hand, the problems sharing the same smallest optimal decision form an interval. As a function of the smallest optimal decision, this interval is strictly increasing. In other words, let and . If , then necessarily . Equivalently, if the problem intervals on which decisions can be the smallest optimal decision are respectively and , then necessarily .
The most common way to determine decision monotonicity is through the quadrangle inequality. In different contexts, this property is also called the Monge property (when describing a matrix ) or submodularity (when describing a function whose variable is an interval).
-
Quadrangle inequality: if, for every ,
then is said to satisfy the quadrangle inequality (abbreviated as “crossing no greater than containing”). If equality always holds, is said to satisfy the quadrangle identity.
Unless otherwise stated, we always assume below. The quadrangle inequality is a sufficient but not necessary condition for decision monotonicity.
Theorem 1
If satisfies the quadrangle inequality, then problem (1) satisfies decision monotonicity.
Proof
We can prove this by contradiction. Suppose that for some , we have . Then . By the optimality conditions, and . Thus, , contradicting the quadrangle inequality.
The quadrangle inequality can be understood as saying that, on a suitable domain, the cost function has a nonpositive second mixed difference .
Using decision monotonicity, many common algorithms can optimize their time complexity to . These algorithms differ in their applicable ranges, implementation difficulty, and running efficiency, so the appropriate algorithm must be chosen for the actual setting. This mainly depends on the properties of . Unless otherwise stated, this article assumes that supports random access, meaning that can be queried or computed in time. However, is not always so easy to compute. Therefore, in addition to the basic case, we discuss methods for optimizing DP with decision monotonicity when has only the following properties:
- Moving access: can be obtained from or by an -time transition. (This is similar to the situation in Mo's algorithm.)
- Dynamic computation: computing depends on . This means that and can only be computed in order. The interval-partition problem without a limit on the number of intervals introduced below belongs to this case.
These two properties are not mutually exclusive: may require dynamic computation while supporting only moving access.
Divide and conquer
To solve all states, it is enough to solve all optimal decision points. For every , solve by first computing , then separately computing, for and for , . At this point, for the first half is known to lie between and , inclusive, while for the second half is known to lie between and , inclusive. Process the two subintervals in the same way until the optimal decision for every problem has been computed. Recording the upper and lower search bounds during the divide-and-conquer process keeps the complexity at . The recursion tree has levels, and each decision point is computed at most twice at each level, so the total number of computations is .
Reference implementation
val_t w(int j, int i); // Cost function
val_t f[N]; // Optimal value
int opt[N]; // Smallest optimal decision
// Recursively solve the problems in [l,r]
// Their smallest optimal decision points are known to lie in [opt_l, opt_r]
void calc(int l, int r, int opt_l, int opt_r) {
int mid = (l + r) / 2;
// Find the optimal decision point for problem mid
for (int j = opt_l; j <= std::min(opt_r, mid); ++j) {
if (w(j, mid) < f[mid]) {
f[mid] = w(j, mid);
opt[mid] = j;
}
}
// Derive the decision intervals of the two parts from decision monotonicity, then recurse
if (l < mid) calc(l, mid - 1, opt_l, opt[mid]);
if (r > mid) calc(mid + 1, r, opt[mid], opt_r);
}
// Solve the problems on the whole interval [1,n]
void solve(int n) {
// The array f must be cleared before every call to the recursive function
std::fill(f + 1, f + n + 1, inf);
// Initially, we only know that every decision for the problems in [1,n] lies in [1,n]
calc(1, n, 1, n);
}
Besides the basic random-access case, the divide-and-conquer algorithm can also handle the case where supports only moving access. During the computation, maintain a cursor and the corresponding value ; whenever a new value is needed, move the cursor directly to the new position and update the function value. The time complexity remains . For a more detailed discussion, see the section Simplified LARSCH algorithm below. However, divide and conquer cannot handle the case where must be computed dynamically, because it cannot compute the smallest optimal decision at the midpoint before the problems in the left half have been solved.
Binary-decision queue
Notice that, for each decision point , the problems for which it can be the smallest optimal decision necessarily form an interval. A monotone queue can record the problem interval that each decision point can solve so far; the optimal solution for a problem can then be obtained naturally from the decision points stored in the queue.
More specifically, the algorithm scans decision points in order. When it reaches decision point , the queue stores a triple consisting of each feasible decision point considered so far and the left and right endpoints and of the interval of problems it can solve. For a problem in the interval , is the smallest optimal decision among all decision points considered so far (that is, the decision points in ). At any moment, the decision points stored in the queue need not be consecutive, but the unresolved problems should be the disjoint union of the problem intervals stored in the queue.
To show that, during queue updates, decision point is the smallest optimal decision for a contiguous interval of problems , we need to strengthen the preceding conclusion slightly:
Corollary 1
Let be the smallest optimal decision when only decisions in are considered, for problem . If satisfies the quadrangle inequality, then for any , we have .
Proof
Let be a sufficiently large positive real number. The function still satisfies the quadrangle inequality, where is the Iverson bracket. Consider the auxiliary DP with as its cost function. In the auxiliary DP, for any problem , a decision cannot be the smallest optimal decision, so . Applying Theorem 1 to the auxiliary DP gives this corollary.
The algorithm proceeds as follows:1
- Initially, the queue is empty. As in a monotone queue, when considering each next decision , perform both a dequeue and an enqueue operation.
- Dequeue: first remove the previous problem from the queue. If the right endpoint of the problem interval solvable by the decision at the front of the queue is exactly , pop the front directly; otherwise, update the left endpoint of the interval solvable by the front decision to .
- Enqueue: to enqueue decision , first compare it with the decision at the back of the queue.
- If, for problem , the decision being enqueued is strictly better than the existing decision , namely , pop the decision from the back. Continue until the queue is empty or the decision at the back is better than for problem .
- If the queue is empty, enqueue , meaning that decision is the optimal solution for all unresolved problems.
- If the decision at the back of the queue is no worse, for problem , than the decision being enqueued, then, when , enqueue , meaning that is the smallest optimal decision for the problems . Otherwise, do not enqueue , because it is not better than the existing decision.
- The final case is that the decision at the back is strictly better than the decision being enqueued for problem , but strictly worse for problem . This means that there is a problem such that the smallest optimal decision for the problems is and the smallest optimal decision for the problems is . Therefore, use binary search to find the smallest satisfying , change the right endpoint of the interval at the back of the queue to , and enqueue .
- Once decision has been processed, all decisions up to have been processed. The decision at the front of the queue is then the smallest optimal decision for problem , so record the corresponding optimal solution.
Reference implementation
val_t w(int j, int i); // Cost function
val_t f[N]; // Optimal value
int opt[N]; // Smallest optimal decision
int lt[N], rt[N]; // Problem interval [l_j,r_j] solvable by decision j
// Solve the problems on the whole interval [1,n]
void solve(int n) {
std::deque<int> dq; // Monotone queue storing all feasible decisions
// Consider all problems and decisions in order; indices start at 1
for (int j = 1; j <= n; ++j) {
// Dequeue
if (!dq.empty() && rt[dq.front()] < j) dq.pop_front();
if (!dq.empty()) lt[dq.front()] = j;
// Enqueue
while (!dq.empty() && w(j, lt[dq.back()]) < w(dq.back(), lt[dq.back()])) {
dq.pop_back();
}
if (dq.empty()) {
lt[j] = j;
rt[j] = n;
dq.emplace_back(j);
} else if (w(j, rt[dq.back()]) >= w(dq.back(), rt[dq.back()])) {
if (rt[dq.back()] < n) {
lt[j] = rt[dq.back()] + 1;
rt[j] = n;
dq.emplace_back(j);
}
} else {
int ll = lt[dq.back()], rr = rt[dq.back()], i = rr;
// Binary search
while (ll <= rr) {
int mm = (ll + rr) / 2;
if (w(j, mm) < w(dq.back(), mm)) {
i = mm;
rr = mm - 1;
} else {
ll = mm + 1;
}
}
rt[dq.back()] = i - 1;
lt[j] = i;
rt[j] = n;
dq.emplace_back(j);
}
// Compute
f[j] = w(dq.front(), j);
opt[j] = dq.front();
}
}
As in a monotone queue, each decision point is enqueued at most once and dequeued at most once. Dequeue is , while enqueue is because it may require binary search, so the total time complexity is .
Because the binary-decision queue algorithm considers all problems and decision points in order, it can handle cases where requires dynamic computation. This is its advantage over divide and conquer. However, because the binary-search step in the algorithm relies on random access to , it cannot handle the case where supports only moving access.
Example 1: [POI2011] Lightning Conductor
Given a sequence of length , , for every , find the smallest nonnegative integer satisfying
Idea
Clearly, rearranging the inequality gives the desired integer . Consider the case first; the other case is similar. We then obtain the state transition
Since is convex, it is easy to see (as described in detail later) that the function satisfies the quadrangle inequality. Applying the algorithm above therefore solves this problem in time.
Implementation
#include <algorithm>
#include <cmath>
#include <deque>
#include <iostream>
#define all \
for (auto i : {&q, &l, &r}) (*i)
using namespace std;
int n, a[500009], ans[500009];
deque<int> q, l, r;
double f(int i, int j) { return a[i] + sqrtl(j - i); }
void work() {
all.clear();
for (int i = 0; i < n; ++i) {
if (q.size() && r.front() < i) all.pop_front(); // Dequeue from the front
if (q.size()) l.front() = i;
for (; q.size() && f(q.back(), l.back()) <= f(i, l.back());) // Dequeue from the back
all.pop_back();
if (q.empty()) // Enqueue
q.emplace_back(i), l.emplace_back(i), r.emplace_back(n);
else if (f(q.back(), n) < f(i, n)) {
int ll = l.back(), rr = n, mid;
for (; ll <= rr;) {
mid = (ll + rr) >> 1;
if (f(q.back(), mid) < f(i, mid))
rr = mid - 1;
else
ll = mid + 1;
}
r.back() = rr;
q.emplace_back(i), l.emplace_back(ll), r.emplace_back(n);
}
ans[i] = max(ans[i], (int)(ceil(f(q.front(), i))) - a[i]);
}
}
int main() {
cin >> n;
for (int i = 0; i < n; cin >> a[i++]);
work();
reverse(a, a + n);
reverse(ans, ans + n);
work();
reverse(ans, ans + n);
for (int i = 0; i < n; cout << ans[i++] << '\n');
}
Simplified LARSCH algorithm
The preceding two algorithms cannot handle the case where requires both dynamic computation and moving access. This section introduces an algorithm that overcomes both difficulties at once. It is a simplified version of the LARSCH algorithm2 proposed by Larmore and Schieber in 1991, hence the name simplified LARSCH algorithm. The original algorithm can solve decision-monotone DP problems in time, but its implementation is more complicated and is not covered here.
We still use divide and conquer. When solving the problems in the interval , assume that we know:
- for problems in , the smallest optimal decision for problem is , together with its optimal value, and
- when only decisions in are considered, the smallest optimal decision for problem is , together with its optimal value.
When solving the problems in is complete, we need the smallest optimal decision and optimal value for every problem in .
Let be the midpoint of . The process is:
- Iterate over decisions , updating the smallest optimal decision and optimal value for problem .
- Recursively solve the problems in .
- Iterate over decisions , updating the optimal value for problem .
- Recursively solve the problems in .
Before recursing on the whole interval , first use decision to update problems . The algorithm terminates when the recursion reaches .
Reference implementation
val_t w(int j, int i); // Cost function
val_t f[N]; // Optimal value
int opt[N]; // Smallest optimal decision
// Update problem i with decision j
void check(int j, int i) {
if (w(j, i) < f[i]) {
f[i] = w(j, i);
opt[i] = j;
}
}
// Recursively solve the problems in (l, r]
void calc(int l, int r) {
int mid = (l + r + 1) / 2;
for (int j = opt[l]; j <= opt[r]; ++j) check(j, mid);
if (mid < r) calc(l, mid);
for (int j = l + 1; j <= mid; ++j) check(j, r);
if (mid > l) calc(mid, r);
}
// Solve the problems on the whole interval [1, n]
void solve(int n) {
// Clear the array f
std::fill(f + 1, f + n + 1, inf);
// Initialization
check(1, 1);
check(1, n);
// Recursively solve the problems in (1, n]
calc(1, n);
}
First, we can establish the correctness of this algorithm. It is enough to check that the prerequisites stated above hold before every recursive step (steps 2 and 4). By Corollary 1 from the preceding section, . Thus, after step 1, is known, so the prerequisites for recursively solving the problems in hold before step 2. Since was already known, step 2 additionally obtains the values of , so after it is known. At the same time, since was already known, after step 3, is known as well. Therefore, the prerequisites for recursively solving the problems in also hold before step 4.
Next, we show that the complexity remains . The recursion tree has levels. For each node at the same level of the recursion tree, the algorithm iterates over the decisions in and , respectively. Since , each decision point is traversed times at any one level. Therefore, the total number of traversals at each level is . If one access or computation of takes time, the algorithm has time complexity .
For cases where supports only moving access, the complexity of this algorithm is still . In this case, maintain separately for steps 1 and 3 a cursor and the current value of . Whenever a new value is needed, move the cursor directly from its previous position to the new position and transition the value of . It is easy to verify that the total number of such direct updates while traversing the recursion tree is . Therefore, the time complexity remains .
Complexity proof for non-random access
We only need to prove that the total number of cursor moves is . Let and be the cursors corresponding to steps 1 and 3, respectively. In fact, before solving the problems in , we can ensure that cursor is at and cursor is at ; afterward, cursor is at and cursor is at .
Consider the following cursor-movement rules. In step 1, move cursor along the path
At this point, both cursors and are at the prescribed positions before solving the problems in . In step 2, as prescribed, cursor moves to and cursor moves to . In step 3, move cursor along the path
At this point, both cursors and are at the prescribed positions before solving the problems in . In step 4, as prescribed, cursor moves to and cursor moves to . Thus both cursors are at the prescribed positions after solving the problems in . This movement rule satisfies the requirements above, and it is sufficient to perform all computations in steps 1 and 3. Directly counting the cursor moves under this rule shows that step 1 requires
moves, while step 3 requires
moves. Summing these move counts over all nodes of the recursion tree, and using the fact that all intervals and at one level can overlap only at endpoints, shows that the total number of moves is .
The movement rule above inserts more waypoints than the cursor uses during the actual computation, so the actual number of cursor moves cannot exceed the estimate under this rule. Hence the actual number of cursor moves is also .
Because this algorithm computes the problems in only after computing the optimal values in , including , it can also handle cases where requires dynamic computation.
Interval-partition problem
Consider partitioning an interval into several subintervals. Formally, partition the given interval into , where , , and for every . The cost of a partition is . The goal is to minimize this cost. The following 1D1D state transition can be written:
Here, . If satisfies the quadrangle inequality, then necessarily satisfies it as well, because the first term contains no crossing term involving and and therefore cancels in the mixed difference. However, because the cost function depends on preceding subproblems, this transition can only be computed in order. Therefore, it cannot use the first divide-and-conquer algorithm described above and is generally suitable only for the binary-decision queue or simplified LARSCH algorithm. The time complexity is .
Fixed number of intervals
The problem above can be strengthened by fixing the number of intervals: partition the interval into exactly subintervals. The number of intervals after partitioning becomes one dimension of the state. The corresponding 2D1D transition is:
Here, , while for every and . By the same reasoning as above, necessarily satisfies the quadrangle inequality. The computation of layer no longer depends on results from that same layer, so every layer can be computed using any algorithm described in the preceding section. The time complexity is .
For this problem, decision monotonicity also permits other optimization algorithms. The second approach relies on the following result and is very similar to the Knuth optimization algorithm described in detail below.
Theorem 2
If satisfies the quadrangle inequality, then for problem (2), .
Proof
The second inequality is simply decision monotonicity within layer . The first inequality is the key point.
We prove . Suppose there are the following two partitions of (with labels in reverse order): and . For every interval, its left endpoint is the smallest optimal decision for the problem ending at its right endpoint; likewise, considering all possible partitions from right to left, its right endpoint is the smallest optimal decision for the problem associated with its left endpoint. For example, and are respectively the smallest optimal right endpoints of the first interval from the left when and are divided into parts. By decision monotonicity, if , equivalently , then necessarily . Therefore, if the claimed inequality were false, we would have , and induction would then prove , contradicting the setup.
The first inequality can also be proved as follows. Again consider the two partitions above. If the claim is false, then ; but since , we can find the smallest such that . Then , and hence . We have found intervals satisfying . Recombine the two partitions as follows. Consider the partition , which has parts. By the assumed optimality,
Likewise, consider the partition , which has parts. Then
The inequality is strict because , while by assumption is the smallest optimal left endpoint among the last intervals of all -part partitions. Adding the two inequalities gives , contradicting the quadrangle inequality. The original claim follows.
Using this result, we can restrict the search range of decision . In the implementation, traverse forward and backward; brute-force search over within the previously established bounds guarantees time.
Note
The complexity here is not . The correct calculation must account for the state matrix. For problem , only decisions satisfying need to be considered, so the total number of decisions scanned by the problems on each antidiagonal (that is, with a fixed ) is . There are such diagonals, giving total time complexity .
The final optimization method starts from the following observation.
Theorem 3
If satisfies the quadrangle inequality, then the optimal value of problem (2) is a convex function of .
Proof
We prove . Consider optimal partitions with and segments, namely and . Let be the smallest index satisfying ; it exists because . By minimality, . Hence . As above, exchange the suffixes of the two existing partitions to obtain:
Both resulting partitions have segments, so optimality gives
The second inequality is exactly the quadrangle inequality, which proves the desired convexity.
This result guarantees that the problem can be solved by WQS binary search (called the Aliens trick abroad). Specifically, consider the parameterized cost function and solve the problem without a limit on the number of intervals, obtaining the optimal value . As the real parameter increases, the number of intervals in the corresponding optimum decreases monotonically. Therefore, binary search can find the parameter for which the optimal number of intervals is exactly ; denote this parameter by . The optimum of the original problem is . Here, the real number can be viewed as the Lagrange multiplier for the interval-count constraint. The implementation has many details; see the WQS binary search page. Its time complexity is , where is a constant.
The three algorithms for interval partitioning with a fixed number of intervals have different advantages at different data scales; choose one according to the specific problem.
Example 3: P4767 [IOI2000] Post Office (enhanced) P6246 [IOI2000] Post Office (further enhanced)
There are some villages beside a highway. The highway is represented by the integer axis, and each village is identified by a single integer coordinate. No two villages are at the same location. The distance between two positions is the absolute value of the difference between their integer coordinates.
Post offices will be built in some, but not necessarily all, of the villages. Choose their locations so that the sum of the distances from each village to its nearest post office is minimized.
Write a program that, given the village positions and the number of post offices, computes the minimum possible total distance from every village to its nearest post office.
Idea
Every village has a nearest post office, and each post office therefore serves a set of villages; this set is clearly an interval.
Divide the villages into intervals and choose one post office in each interval.
By elementary mathematics, for interval , the post office should be built at the -th village. Prefix sums make easy to compute.
The problem is now an interval-partition problem with a fixed number of intervals. The function can be shown to satisfy the quadrangle inequality, so the optimizations above apply directly.
Implementation 1, the second optimization above, complexity
#include <iostream>
constexpr int N = 3009;
constexpr int M = 309;
using namespace std;
int n, m, a[N], s[N], g[M][N], p[M][N];
int f(int i, int j) {
int k = (i + j) >> 1;
return a[k] * (k - i + 1) - (s[k] - s[i - 1]) + (s[j] - s[k]) -
a[k] * (j - k);
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; cin >> a[i], s[i] = s[i - 1] + a[i], ++i);
for (int i = 1; i <= n; ++i) g[0][i] = 1 << 30, p[m + 1][i] = i;
for (int i = 1; i <= m; ++i) p[i][0] = 1;
for (int i = 1; i <= n; ++i)
for (int j = m; j; --j) {
g[j][i] = 1 << 30;
for (int k = p[j][i - 1]; k <= p[j + 1][i]; ++k) {
int tmp = g[j - 1][k - 1] + f(k, i);
if (tmp < g[j][i]) g[j][i] = tmp, p[j][i] = k;
}
}
cout << g[m][n];
}
Implementation 2, WQS binary search, complexity
#include <deque>
#include <iostream>
#define all \
for (auto i : {&q, &l, &r}) (*i)
using namespace std;
long long n, m, a[500009], s[500009], u, v, w, sum[500009], cnt[500009];
deque<int> q, l, r;
long long f(int i, int j) {
int k = (i + j) >> 1;
return sum[i - 1] + v + a[k] * (k - i + 1) - (s[k] - s[i - 1]) +
(s[j] - s[k]) - a[k] * (j - k);
}
void work() {
all.clear();
for (int i = 1; i <= n; ++i) {
if (q.size() && r.front() < i) all.pop_front(); // Dequeue from the front
if (q.size()) l.front() = i;
for (; q.size() && f(q.back(), l.back()) >= f(i, l.back());) // Dequeue from the back
all.pop_back();
if (q.empty()) // Enqueue
q.emplace_back(i), l.emplace_back(i), r.emplace_back((int)n);
else if (f(q.back(), n) >= f(i, n)) {
int ll = l.back(), rr = n, mid;
for (; ll <= rr;) {
mid = (ll + rr) >> 1;
if (f(q.back(), mid) >= f(i, mid))
rr = mid - 1;
else
ll = mid + 1;
}
r.back() = rr;
q.emplace_back(i), l.emplace_back(ll), r.emplace_back((int)n);
}
sum[i] = f(q.front(), i);
cnt[i] = cnt[q.front() - 1] + 1;
}
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; cin >> a[i], s[i] = s[i - 1] + a[i], ++i);
for (w = 2e12; u <= w;) { // WQS binary search
v = (u + w) >> 1;
work();
if (cnt[n] < m)
w = v - 1;
else
u = v + 1;
}
v = w;
work();
cout << sum[n] - m * v;
}
Interval-merging problem
Another class of dynamic programs that can be optimized by the quadrangle inequality is the interval-merging problem: repeatedly merge the unit intervals until obtaining . Each time and are merged, pay cost . The goal is to find a merging order with minimum total cost. The corresponding 2D1D transition is:
The initial cost is . The brute-force algorithm has total complexity , while decision monotonicity reduces it to . This algorithm was first proposed by Knuth for the optimal binary search tree problem and was further studied and summarized by Yao Chufeng; internationally it is called Knuth's optimization or the Knuth–Yao speedup.
In addition to the quadrangle inequality, decision monotonicity for interval merging requires the cost function to satisfy interval-containment monotonicity.
-
Interval-containment monotonicity: if, for all ,
then is said to be monotone under interval containment.
This is essentially a first-order condition on the cost function: decreases with and increases with .
Lemma 1
If satisfies interval-containment monotonicity and the quadrangle inequality, then the state satisfies the quadrangle inequality.
Proof
Assume without loss of generality that . We prove by induction on . If or , the claim is an equality. In the general case, split into cases according to the position of .
In the first case, or , meaning that is contained in either or .
Without loss of generality, assume ; the other case is analogous. Then
Here, the first inequality follows from the induction hypothesis , the second from interval-containment monotonicity , and the third from the optimality condition .
In the second case, , so lies in . Consider the position of .
Without loss of generality, assume , meaning that is contained in ; the other case is analogous. Then
Here, the first inequality follows from the induction hypothesis , the second from the quadrangle inequality , and the third from the optimality conditions for and .
Theorem 4
If satisfies interval-containment monotonicity and the quadrangle inequality, then the smallest optimal decision in problem (3) satisfies
Proof
Lemma 1 proves that satisfies the quadrangle inequality. Therefore, the objective , for fixed , satisfies the quadrangle inequality as a function of , so Theorem 1 gives . Terms that do not simultaneously contain do not affect the quadrangle inequality. Similarly, for fixed , it satisfies the quadrangle inequality as a function of , so . This proves the result.
Using this result, we can likewise restrict the search range of decision point . Traverse interval lengths in increasing order, then traverse all intervals of that length. Brute-force all between and to obtain and record . For each fixed length, the total decision-space size is , and there are possible lengths, so the total complexity is .
Reference implementation
val_t w(int j, int i); // Cost function
val_t f[N][N]; // Optimal values
int opt[N][N]; // Smallest optimal decisions
// Solve the problem for the whole interval [1,n]
void solve(int n) {
// Initialize
for (int i = 1; i <= n; ++i) {
f[i][i] = 0;
opt[i][i] = i;
}
// Enumerate interval lengths
for (int len = 2; len <= n; ++len) {
// Enumerate all intervals of length len
for (int j = 1, i = len; i <= n; ++j, ++i) {
f[j][i] = inf;
for (int k = opt[j][i - 1]; k <= opt[j + 1][i]; ++k)
if (f[j][i] > f[j][k] + f[k + 1][i] + w(j, i)) {
f[j][i] = f[j][k] + f[k + 1][i] + w(j, i); // Update the state value
opt[j][i] = k; // Update the (smallest) optimal decision
}
}
}
}
Classes of functions satisfying the quadrangle inequality
The following properties make it easier to prove that a function satisfies the quadrangle inequality.
Property 1: If and both satisfy the quadrangle inequality (or interval-containment monotonicity), then for any , also satisfies the same property.
Property 2: If there are functions and such that , then satisfies the quadrangle identity. If and are increasing, also satisfies interval-containment monotonicity.
Property 3: Let be an increasing convex function. If satisfies the quadrangle inequality and interval-containment monotonicity, then also satisfies both.
Property 4: Let be convex. If satisfies the quadrangle identity and interval-containment monotonicity, then satisfies the quadrangle inequality.
One clarification is needed first. Textbooks differ on the definition of a convex function; here, convex means lower-convex, that is, its first derivative is increasing when differentiable.
Proof
The first two properties follow directly from the definitions. We prove Property 3; Property 4 is analogous. Since is monotone, automatically preserves interval-containment monotonicity. The key point is the quadrangle inequality.
Consider the mixed second difference over .
By interval-containment monotonicity, and . Convexity of gives, for , , so the last two lines are nonpositive. The quadrangle inequality gives ; since is increasing, the difference in the first line is also nonpositive. Thus the total mixed second difference is nonpositive, which is the quadrangle inequality.
This proof is the discrete version of the following derivative proof.
This is immediate when , , , , and . Interval-containment monotonicity gives the first-order conditions on , while the quadrangle inequality gives the second-order condition.
Exercises
- Codeforces - Ciel and Gondolas(Be careful with I/O!)
- SPOJ - LARMY
- CodeChef - CHEFAOR
- HackerRank - Guardians of the Lunatics
- ACM ICPC World Finals 2017 - Money
References and notes
- Quora answer by Michael Levin
- Video tutorial by “Sothe” the Algorithm Wolf
- Divide and Conquer DP
- Knuth's Optimization
- Quadrangle Inequality Properties
- Wang Qinshi, “An Analysis of a Class of Binary-Search Methods”
- Simplified LARSCH Algorithm by noshi91
- Quadrangle inequality and decision monotonicity by b6e0_
- A simplified LARSCH algorithm for online decision monotonicity by Register_int
Footnotes
-
“Worse” and “better” in the algorithm descriptions refer to lexicographic order: compare function values first, then decision points. “Better” means either a smaller function value or the same value with a smaller decision point. ↩
-
Larmore, Lawrence L., and Baruch Schieber. “On-line dynamic programming with applications to the prediction of RNA secondary structure.” Journal of Algorithms 12, no. 3 (1991): 490–515. ↩