14. Dynamic Programming
Exercises
14.1-1
Available in the latest revision of the IM.
14.1-2
Available in the latest revision of the IM.
14.1-3
Available in the latest revision of the IM.
14.1-4
Available in the latest revision of the IM.
14.1-5
Available in the latest revision of the IM.
14.1-6
Available in the latest revision of the IM.
The solution in the IM sets F0=1 instead of F0=0. Furthermore, it uses O(n) space instead of O(1). The subproblem graph clearly reveals that we only need to keep the last two values to compute the next element of the sequence.
14.2-1
Available in the latest revision of the IM.
14.2-2
Available in the latest revision of the IM.
14.2-3
Available in the latest revision of the IM.
14.2-4
Available in the latest revision of the IM.
14.2-5
Available in the latest revision of the IM.
14.2-6
Available in the latest revision of the IM.
14.3-1
Available in the latest revision of the IM.
14.3-2
Available in the latest revision of the IM.
14.3-3
Available in the latest revision of the IM.
14.3-4
The IM solution is broken, as it doesn't select k to minimize the quantity pi−1pkpj.
Let p0=1,p1=2,p2=10,p3=3. The greedy strategy would pick k=1, resulting in the parenthesization A1(A2A3) that costs 66. Nonetheless, computing the product as (A1A2)A3 costs only 50.
14.3-5
Available in the latest revision of the IM.
14.4-1
Available in the latest revision of the IM.
14.4-2
Available in the latest revision of the IM.
14.4-3
Available in the latest revision of the IM.
The code in the IM lacks the base cases (when i=0∨j=0 then cij=0).
14.4-4
Available in the latest revision of the IM.
14.4-5
Available in the latest revision of the IM.
★ 14.4-6
The solution is available here. To handle duplicates turn each number into an ordered pair (ai,i), where i is its index. This converts the problem of finding the longest monotonically increasing subsequence of a sequence of n numbers into finding the longest strictly increasing subsequence of a sequence of n ordered pairs.
14.5-1
Available in the latest revision of the IM.
14.5-2
Available in the latest revision of the IM.
14.5-3
Available in the latest revision of the IM.
★ 14.5-4
Using Knuth's optimization, the innermost loop (which searches for the optimal root) no longer runs from i to j (see line 10 of the Optimal-BST function). Instead, it only searches between root[i, j - 1] and root[i + 1, j] for i<j. When i=j then root[i, i] = i. Observe that these entries are already filled in, since they are related to intervals of smaller lengths.
For more details consult the tutorial about OBST. Section 2.1.2 derives the O(n2) upper bound, which matches the lower bound, too. The provided sum massively telescopes, which ensures the Θ(n2) running time. The paper also contains the proof of the monotonicity of roots.
Problems
14-1 Longest simple path in a directed acyclic graph
Available in the latest revision of the IM.
The alternative solution in the IM to broken. Since the direction is flipped, we cannot use forward references as in the top-down variant. Below is the fixed version.
14-2 Longest palindrome subsequence
Available in the latest revision of the IM.
14-3 Bitonic euclidean traveling-salesperson problem
Available in the latest revision of the IM.
The solution in the IM prints out the tour in opposite direction, starting from the rightmost point. Of course, this doesn't change the essence of the problem.
14-4 Printing neatly
Available in the latest revision of the IM.
There is a small error in the text about reconstructing the sequene of words. Namely, the second-to-last line starts at p[p[n] - 1] and goes through word p[n]-1.
14-5 Edit distance
Available in the latest revision of the IM.
14-6 Planning a company party
Available in the latest revision of the IM.
14-7 Viterbi algorithm
a.
The problem asks us to find a valid path through a graph that matches a specific sequence of edge labels. We can model this using a layer-by-layer approach similar to Breadth-First Search (BFS), combined with the memoization aspect of dynamic programming.
We can solve this by maintaining a set of "reachable states" at each step of the sequence. Let Si be the set of all vertices we could possibly be at after successfully traversing the first i sounds of the sequence s.
Base Case: At step 0 (before making any moves), the only reachable vertex is the starting vertex v0. Thus, S0={v0}.
Transitions: To compute Si (the reachable vertices after matching the i-th sound, σi), we look at every vertex u in Si−1. If there is an outgoing edge from u to some vertex v with the label σi, we add v to Si.
Tracking the Path: To reconstruct the path at the end, we maintain a 2D table
pred[i, v]that records the predecessor vertex u that led to v at step i. It also acts as sort of a "visited" check for a given layer. If at any point Si becomes empty, it means the sequence cannot be matched, and we returnNO-SUCH-PATH. If we successfully reach Sk, we can pick any vertex in Sk and backtrack using thepredtable to output the path.
The total running time is O(k(∣V∣+∣E∣)). The space complexity is O(k∣V∣) for storing the pred table (this also upper bounds the size of the queue).
b.
Because the queue enforces a strict layer-by-layer traversal, by the time a pair (v,i+1) is dequeued, every single possible path of length i has already been evaluated. Therefore, prob[i + 1, v] is mathematically guaranteed to contain the absolute maximum probability for reaching v at that step, and it is safe to use it to compute the next layer.
The time and space complexity remains the same as before.
14-8 mage compression by seam carving
Available in the latest revision of the IM.
14-9 Breaking a string
Available in the latest revision of the IM.
14-10 Planning an investment strategy
a.
To prove that there is always an optimal strategy that puts all the money into a single investment each year, we can evaluate the mathematics of a split portfolio versus a single-investment portfolio, factoring in the flat fee structure. Let’s define an "epoch" as any continuous block of time from year a to year b where no switching occurs (meaning only the f1 fee is paid each year). For this period, compute the cumulative rate of investment i as Ri(ab)=∏k=abrik. If Rmax(ab) is the highest cumulative rate among all the investments over these years, then:
where d represents the amount of money and xi the fraction of this money put into investment i, such that ∑i=1nxi=1. So, even if a high f2 fee forces a multi-year hold, identifying the single investment with the highest cumulative rate for that period and putting 100% of the money into it will always yield an equal or greater return than diversifying.
This means the entire 10-year strategy can be mathematically reduced to:
Choosing the optimal duration for each epoch.
Choosing the single best investment to hold during that epoch.
Paying the f2 switching fee strictly at the boundaries between epochs.
This constitutes an existential proof of an optimal investment strategy that, in each year, puts all the money into a single investment.
b.
From part (a), we know that inside each epoch we should put all the money into a single investment with highest cumulative rate. Let m[i,j] be the maximum amount of money we can have at the end of year j, given that our money is in investment i for that year. To calculate the optimal value for the prefix problem (1,j) ending in investment i, we only need to look at the independent, already-optimized subproblems from year j−1. The cut-and-paste argument clearly applies. Therefore,
c.
The running time is Θ(n2) and the space complexity is Θ(n). This applies for a fixed 10-year period.
d.
In our previous proofs, the problem relied on monotonicity: having more total money at the end of year j<10 strictly meant we could generate more money at year 10. Once a $15,000 cap is introduced, capital is no longer just a single number—its distribution matters. If we aggressively maximize our money in year j by pouring it all into one high-yield investment, we will hit the cap. To continue growing, we will be forced to split our money across multiple investments in year j+1, which triggers the potentially massive f2 fee. To avoid that fee, a globally optimal strategy might require us to intentionally "underperform" in earlier years by splitting our money early, perfectly positioning our portfolio to ride high rates later without ever hitting a cap or paying a fee.
14-11 Inventory planning
Available in the latest revision of the IM.
14-12 Signing free-agent baseball players 🌟
This exercise is a variation of the famous knapsack problem.
Available in the latest revision of the IM.
The solution in the IM doesn't consider an important detail from the description. Namely, the problem explicitly states that every player signs for a multiple of $100,000; we can drastically optimize the space and time complexity by scaling the budget.
Let X=⌊X/100,000⌋.
For each player p, let p.cost=p.cost/100,000.
Last updated