Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f803477

Browse files
author
Oleksandr Kulkov
authored
Merge pull request #833 from omkarbajaj073/master
Added article on Knuth's optimization; single sentence addition to divide and conquer dp
2 parents 4f04900 + e179fdc commit f803477

File tree

3 files changed

+200
-8
lines changed

3 files changed

+200
-8
lines changed

src/dynamic_programming/divide-and-conquer-dp.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,17 @@ Divide and Conquer is a dynamic programming optimization.
44

55
### Preconditions
66
Some dynamic programming problems have a recurrence of this form: $$dp(i, j) =
7-
\min_{0 \leq k \leq j} \\{ dp(i - 1, k - 1) + C(k, j) \\}$$ Where $C(k, j)$ is a cost
8-
function and $dp(i, j) = 0$ when $j \lt 0$.
7+
\min_{0 \leq k \leq j} \\{ dp(i - 1, k - 1) + C(k, j) \\}$$, where $C(k, j)$ is a cost
8+
function and $dp(i, j) = 0$ when $j \lt 0$.
99

1010
Say $0 \leq i \lt m$ and $0 \leq j \lt n$, and evaluating $C$ takes $O(1)$
1111
time. Then the straightforward evaluation of the above recurrence is $O(m n^2)$. There
1212
are $m \times n$ states, and $n$ transitions for each state.
1313

14-
Let $opt(i, j)$ be the value of $k$ that minimizes the above expression. If
15-
$opt(i, j) \leq opt(i, j + 1)$ for all $i, j$, then we can apply
16-
divide-and-conquer DP. This is known as the _monotonicity condition_. The optimal
14+
Let $opt(i, j)$ be the value of $k$ that minimizes the above expression. Assuming that the
15+
cost function satisfies the qudrangle inequality, we can show that
16+
$opt(i, j) \leq opt(i, j + 1)$ for all $i, j$. This is known as the _monotonicity condition_.
17+
Then, we can apply divide and conquer DP. The optimal
1718
"splitting point" for a fixed $i$ increases as $j$ increases.
1819

1920
This lets us solve for all states more efficiently. Say we compute $opt(i, j)$
@@ -80,9 +81,9 @@ int solve() {
8081
### Things to look out for
8182
8283
The greatest difficulty with Divide and Conquer DP problems is proving the
83-
monotonicity of $opt$. Many Divide and Conquer DP problems can also be solved
84-
with the Convex Hull trick or vice-versa. It is useful to know and understand
85-
both!
84+
monotonicity of $opt$. One special case where this is true is when the cost function satisfies the quadrangle inequality, i.e., $C(a, c) + C(b, d) \leq C(a, d) + C(b, c)$ for all $a \leq b \leq c \leq d$.
85+
Many Divide and Conquer DP problems can also be solved with the Convex Hull trick or vice-versa. It is useful to know and understand
86+
both!
8687
8788
## Practice Problems
8889
- [AtCoder - Yakiniku Restaurants](https://atcoder.jp/contests/arc067/tasks/arc067_d)
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
# Knuth's Optimization
2+
3+
Knuth's optimization, also known as the Knuth-Yao Speedup, is a special case of dynamic programming on ranges, that can optimize the time complexity of solutions by a linear factor, from $O(n^3)$ for standard range DP to $O(n^2)$.
4+
5+
## Conditions
6+
7+
The Speedup is applied for transitions of the form
8+
9+
$$dp(i, j) = \min_{i \leq k < j} [ dp(i, k) + dp(k+1, j) + C(i, j) ].$$
10+
11+
Similar to [divide and conquer DP](../divide-and-conquer-dp.md), let $opt(i, j)$ be the value of $k$ that minimizes the expression in the transition ($opt$ is referred to as the "optimal splitting point" further in this article). The optimization requires that the following holds:
12+
13+
$$opt(i, j-1) \leq opt(i, j) \leq opt(i+1, j).$$
14+
15+
We can show that it is true when the cost function $C$ satisfies the following conditions for $a \leq b \leq c \leq d$:
16+
17+
1. $C(b, c) \leq C(a, d)$;
18+
19+
2. $C(a, c) + C(b, d) \leq C(a, d) + C(b, c)$ (the quadrangle inequality [QI]).
20+
21+
This result is proved further below.
22+
23+
## Algorithm
24+
25+
Let's process the dp states in such a way that we calculate $dp(i, j-1)$ and $dp(i+1, j)$ before $dp(i, j)$, and in doing so we also calculate $opt(i, j-1)$ and $opt(i+1, j)$. Then for calculating $opt(i, j)$, instead of testing values of $k$ from $i$ to $j-1$, we only need to test from $opt(i, j-1)$ to $opt(i+1, j)$. To process $(i,j)$ pairs in this order it is sufficient to use nested for loops in which $i$ goes from the maximum value to the minimum one and $j$ goes from $i+1$ to the maximum value.
26+
27+
### Generic implementation
28+
29+
Though implementation varies, here's a fairly generic
30+
example. The structure of the code is almost identical to that of Range DP.
31+
32+
```{.cpp file=knuth_optimization}
33+
34+
int solve() {
35+
int N;
36+
... // read N and input
37+
int dp[N][N], opt[N][N];
38+
39+
auto C = [&](int i, int j) {
40+
... // Implement cost function C.
41+
};
42+
43+
for (int i = 0; i < N; i++) {
44+
opt[i][i] = i;
45+
... // Initialize dp[i][i] according to the problem
46+
}
47+
48+
for (int i = N-2; i >= 0; i--) {
49+
for (int j = i+1; j < N; j++) {
50+
int mn = INT_MAX;
51+
int cost = C(i, j);
52+
for (int k = opt[i][j-1]; k <= min(j-1, opt[i+1][j]); k++) {
53+
if (mn >= dp[i][k] + dp[k+1][j] + cost) {
54+
opt[i][j] = k;
55+
mn = dp[i][k] + dp[k+1][j] + cost;
56+
}
57+
}
58+
dp[i][j] = mn;
59+
}
60+
}
61+
62+
cout << dp[0][N-1] << endl;
63+
}
64+
```
65+
66+
### Complexity
67+
68+
A complexity of the algorithm can be estimated as the following sum:
69+
70+
$$
71+
\sum\limits_{i=1}^N \sum\limits_{j=i+1}^N [opt(i+1,j)-opt(i,j-1)] =
72+
\sum\limits_{i=1}^N \sum\limits_{j=i}^{N-1} [opt(i+1,j+1)-opt(i,j)].
73+
$$
74+
75+
As you see, most of the terms in this expression cancel each other out, except for positive terms with $j=N$ and negative terms with $i=1$. Thus, the whole sum can be estimated as
76+
77+
$$
78+
\sum\limits_{k=1}^N[opt(k,N)-opt(1,k)] = O(n^2),
79+
$$
80+
81+
rather than $O(n^3)$ as it would be if we were using a regular range DP.
82+
83+
### On practice
84+
85+
The most common application of Knuth's optimization is in Range DP, with the given transition. The only difficulty is in proving that the cost function satisfies the given conditions. The simplest case is when the cost function $C(i, j)$ is simply the sum of the elements of the subarray $S[i, i+1, ..., j]$ for some array (depending on the question). However, they can be more complicated at times.
86+
87+
Note that more than the conditions on the dp transition and the cost function, the key to this optimization is the inequality on the optimum splitting point. In some problems, such as the optimal binary search tree problem (which is, incidentally, the original problem for which this optimization was developed), the transitions and cost functions will be less obvious, however, one can still prove that $opt(i, j-1) \leq opt(i, j) \leq opt(i+1, j)$, and thus, use this optimization.
88+
89+
90+
### Proof of correctness
91+
92+
To prove the correctness of this algorithm in terms of $C(i,j)$ conditions, it suffices to prove that
93+
94+
$$
95+
opt(i, j-1) \leq opt(i, j) \leq opt(i+1, j)
96+
$$
97+
98+
assuming the given conditions are satisfied.
99+
100+
!!! lemma "Lemma"
101+
$dp(i, j)$ also satisfies the quadrangle inequality, given the conditions of the problem are satisfied.
102+
103+
??? hint "Proof"
104+
The proof for this lemma uses strong induction. It has been taken from the paper <a href="https://dl.acm.org/doi/pdf/10.1145/800141.804691">Efficient Dynamic Programming Using Quadrangle Inequalities</a>, authored by F. Frances Yao, which introduced the Knuth-Yao Speedup (this particular statement is Lemma 2.1 in the paper). The idea is to induct on the length $l = d - a$. The case where $l = 1$ is trivial. For $l > 1$ consider 2 cases:
105+
106+
1. $b = c$
107+
The inequality reduces to $dp(a, b) + dp(b, d) \leq dp(a, d)$ (This assumes that $dp(i, i) = 0$ for all $i$, which is the case for all problems using this optimization). Let $opt(a,d) = z$.
108+
109+
- If $z < j$,
110+
Note that
111+
112+
$$
113+
dp(a, b) \leq dp_{z}(a, b) = dp(a, z) + dp(z+1, b) + C(a, b).
114+
$$
115+
116+
Therefore,
117+
118+
$$
119+
dp(a, b) + dp(b, d) \leq dp(a, z) + dp(z+1, b) + dp(b, d) + C(a, b)
120+
$$
121+
122+
From the induction hypothesis, $dp(z+1, b) + dp(b, d) \leq dp(z+1, d)$. Also, it is given that $C(a, b) \leq C(a, d)$. Combining these 2 facts with above inequality yields the desired result.
123+
124+
- If $z \geq j$, the proof of this case is symmetric to the previous case.
125+
126+
2. $b < c$
127+
Let $opt(b, c) = z$ and $opt(a, d) = y$.
128+
129+
- If $z \leq y$,
130+
131+
$$
132+
dp(a, c) + dp(b, d) \leq dp_{z}(a, c) + dp_{y}(b, d)
133+
$$
134+
135+
where
136+
137+
$$
138+
dp_{z}(a, c) + dp_{y}(b, d) = C(a, c) + C(b, d) + dp(a, z) + dp(z+1, c) + dp(b, y) + dp(y+1, d).
139+
$$
140+
141+
Using the QI on $C$ and on the dp state for the indices $z+1 \leq y+1 \leq c \leq d$ (from the induction hypothesis) yields the desired result.
142+
143+
- If $z > y$, the proof of this case is symmetric to the previous case.
144+
145+
This completes the proof of the lemma.
146+
147+
Now, consider the following setup. We have 2 indices $i \leq p \leq q < j$. Set $dp_{k} = C(i, j) + dp(i, k) + dp(k+1, j)$.
148+
149+
Suppose we show that
150+
151+
$$
152+
dp_{p}(i, j-1) \geq dp_{q}(i, j-1) \implies dp_{p}(i, j) \geq dp_{q}(i, j).
153+
$$
154+
155+
Setting $q = opt(i, j-1)$, by definition, $dp_{p}(i, j-1) \geq dp_{q}(i, j-1)$. Therefore, applying the inequality to all $i \leq p \leq q$, we can infer that $opt(i, j)$ is at least as much as $opt(i, j-1)$, proving the first half of the inequality.
156+
157+
Now, using the QI on some indices $p+1 \leq q+1 \leq j-1 \leq j$, we get
158+
159+
$$\begin{align}
160+
&dp(p+1, j-1) + dp(q+1, j) ≤ dp(q+1, j-1) + dp(p+1, j) \\
161+
\implies& (dp(i, p) + dp(p+1, j-1) + C(i, j-1)) + (dp(i, q) + dp(q+1, j) + C(i, j)) \\
162+
\leq& (dp(i, q) + dp(q+1, j-1) + C(i, j-1)) + (dp(i, p) + dp(p+1, j) + C(i, j)) \\
163+
\implies& dp_{p}(i, j-1) + dp_{q}(i, j) ≤ dp_{p}(i, j) + dp_{q}(i, j-1) \\
164+
\implies& dp_{p}(i, j-1) - dp_{q}(i, j-1) ≤ dp_{p}(i, j) - dp_{q}(i, j) \\
165+
\end{align}$$
166+
167+
Finally,
168+
169+
$$\begin{align}
170+
&dp_{p}(i, j-1) \geq dp_{q}(i, j-1) \\
171+
&\implies 0 \leq dp_{p}(i, j-1) - dp_{q}(i, j-1) \leq dp_{p}(i, j) - dp_{q}(i, j) \\
172+
&\implies dp_{p}(i, j) \geq dp_{q}(i, j)
173+
\end{align}$$
174+
175+
This proves the first part of the inequality, i.e., $opt(i, j-1) \leq opt(i, j)$. The second part $opt(i, j) \leq opt(i+1, j)$ can be shown with the same idea, starting with the inequality
176+
$dp(i, p) + dp(i+1, q) ≤ dp(i+1, p) + dp(i, q)$.
177+
178+
This completes the proof.
179+
180+
## Practice Problems
181+
- [UVA - Cutting Sticks](https://onlinejudge.org/external/100/10003.pdf)
182+
- [UVA - Prefix Codes](https://onlinejudge.org/external/120/12057.pdf)
183+
- [SPOJ - Breaking String](https://www.spoj.com/problems/BRKSTRNG/)
184+
- [UVA - Optimal Binary Search Tree](https://onlinejudge.org/external/103/10304.pdf)
185+
186+
187+
## References
188+
- [Geeksforgeeks Article](https://www.geeksforgeeks.org/knuths-optimization-in-dynamic-programming/)
189+
- [Doc on DP Speedups](https://home.cse.ust.hk/~golin/COMP572/Notes/DP_speedup.pdf)
190+
- [Efficient Dynamic Programming Using Quadrangle Inequalities](https://dl.acm.org/doi/pdf/10.1145/800141.804691)

src/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ Full list of updates: [Commit History](https://github.com/e-maxx-eng/e-maxx-eng/
7979

8080
- **DP optimizations**
8181
- [Divide and Conquer DP](dynamic_programming/divide-and-conquer-dp.md)
82+
- [Knuth's Optimization](dynamic_programming/knuth-optimization.md)
8283
- **Tasks**
8384
- [Dynamic Programming on Broken Profile. Problem "Parquet"](dynamic_programming/profile-dynamics.md)
8485
- [Finding the largest zero submatrix](dynamic_programming/zero_matrix.md)

0 commit comments

Comments
 (0)