Section 5 · 8 min read
Dynamic programming
When and how to use dynamic programming, with the standard GATE formulations: LCS, 0/1 knapsack, matrix chain multiplication, Floyd-Warshall and Bellman-Ford.
On this page
The idea
Dynamic programming (DP) solves a problem by expressing its answer in terms of answers to smaller subproblems, then computing each subproblem once and storing it. It applies when the problem has:
- Optimal substructure: an optimal solution is built from optimal solutions of subproblems.
- Overlapping subproblems: the same subproblems appear many times in a plain recursion.
Without overlap, plain divide and conquer is enough. Without optimal substructure, no recurrence exists. Naive recursive Fibonacci makes calls; storing cuts this to .
Two styles
- Memoisation (top-down): write the recursion, cache each result the first time it is computed. Only reachable subproblems are solved.
- Tabulation (bottom-up): fill a table in an order where every dependency is ready. No recursion overhead, and rows that are no longer needed can be discarded to save space.
Recipe
- Define the subproblem precisely (what does mean?).
- Write the recurrence, including base cases.
- Fix an evaluation order.
- Running time = number of subproblems work per subproblem.
- Recover the solution itself by storing the choice made at each cell.
Longest common subsequence
A subsequence keeps order but may skip characters. For and , let be the LCS length of the prefixes and .
Time and space . The length alone needs only two rows, space. Related: shortest common supersequence length ; minimum deletions plus insertions to turn into .
0/1 knapsack
Items with weights and values , capacity . is the best value using items with capacity .
Time . This is pseudo-polynomial: polynomial in the value of , but exponential in the number of bits of . 0/1 knapsack is NP-hard, so this does not contradict anything. With a one-dimensional array, loop from down to so each item is used once; looping upward gives the unbounded knapsack instead.
Subset sum is the same table with boolean entries: .
Matrix chain multiplication
Matrix has dimensions . Multiplying a by a matrix costs scalar multiplications. is the minimum cost of computing .
Fill by increasing chain length. subproblems, choices each: time, space. The number of parenthesisations of matrices is the Catalan number , which grows exponentially, so brute force is hopeless.
Floyd-Warshall (all-pairs shortest paths)
is the shortest path whose intermediate vertices are all in .
for k = 1 to V:
for i = 1 to V:
for j = 1 to V:
if d[i][k] + d[k][j] < d[i][j]:
d[i][j] = d[i][k] + d[k][j]
Time , space (one matrix can be updated in place). Handles negative edges. A negative cycle shows up as . The loop over must be outermost. Replacing by gives Warshall's transitive closure.
Bellman-Ford (single source, negative edges allowed)
is the shortest path to using at most edges: . A shortest simple path has at most edges, so rounds suffice.
d[s] = 0; d[v] = infinity for v != s
repeat V - 1 times:
for each edge (u, v, w):
if d[u] + w < d[v]: d[v] = d[u] + w
for each edge (u, v, w):
if d[u] + w < d[v]: report negative cycle
Time . In practice the in-place version may converge earlier, depending on edge order; it can stop as soon as a full pass changes nothing.
Other standard DPs
| Problem | Subproblem | Time |
|---|---|---|
| Edit distance | prefixes , | |
| Longest increasing subsequence | LIS ending at | , or with patience sorting |
| Coin change (number of ways) | amount using first coins | |
| Rod cutting | best value for length | |
| Optimal BST | keys | |
| Travelling salesman (Held-Karp) | subset , end vertex |
Worked examples
Worked example 1: LCS table
Find the LCS length of ACBDAB and BDCABA.
The filled table (rows are prefixes of , columns of , row 0 and column 0 omitted):
| B | D | C | A | B | A | |
|---|---|---|---|---|---|---|
| A | 0 | 0 | 0 | 1 | 1 | 1 |
| C | 0 | 0 | 1 | 1 | 1 | 1 |
| B | 1 | 1 | 1 | 1 | 2 | 2 |
| D | 1 | 2 | 2 | 2 | 2 | 2 |
| A | 1 | 2 | 2 | 3 | 3 | 3 |
| B | 1 | 2 | 2 | 3 | 4 | 4 |
The answer is the bottom-right cell, 4. Tracing back through diagonal moves gives BDAB, one LCS of length 4.
Worked example 2: 0/1 knapsack
Capacity 7, items (weight, value): (1, 1), (3, 4), (4, 5), (5, 7).
Rows after each item, capacities 0 to 7:
| Items used | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
| {1} | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
| {1, 2} | 0 | 1 | 1 | 4 | 5 | 5 | 5 | 5 |
| {1, 2, 3} | 0 | 1 | 1 | 4 | 5 | 6 | 6 | 9 |
| {1, 2, 3, 4} | 0 | 1 | 1 | 4 | 5 | 7 | 8 | 9 |
Answer 9, from items 2 and 3 (weights 3 + 4). The ratio-greedy choice (5, 7) then (1, 1) gives only 8.
Worked example 3: Matrix chain
Dimensions , so four matrices.
- Length 2: , , .
- .
- .
- .
Optimal order with 405 multiplications.
Worked example 4: Floyd-Warshall
Directed graph on vertices 1 to 4: (4), (9), (3), (7), (1), (6), (2).
After (paths through vertex 1): , , . After : , , . After : , , . After : , , . Final matrix:
Worked example 5: Bellman-Ford needs every pass
Vertices s, a, b, c, t. Edges relaxed in this order each pass: (4), (), (5), (), (6), (7), (9).
- Pass 1: , , (only edges out of s and b are usable).
- Pass 2: , .
- Pass 3: .
- Pass 4: .
Final: , , , . The worst edge order made the shortest path (4 edges) need all passes.
Common traps
- 0/1 knapsack in is not a polynomial algorithm.
- LCS is not the longest common substring; substrings must be contiguous and use a different recurrence ( on mismatch).
- Matrix chain needs , not . Write the dimension vector carefully.
- Floyd-Warshall with in an inner loop is wrong.
- Bellman-Ford pass values depend on edge order; final values do not.
- Coin change "number of ways" with coins in the outer loop counts combinations; with amounts in the outer loop it counts ordered sequences.
Quick revision
- DP = optimal substructure + overlapping subproblems.
- LCS, edit distance: . Matrix chain: . 0/1 knapsack: , pseudo-polynomial.
- Floyd-Warshall: , negative edges fine, means a negative cycle.
- Bellman-Ford: , passes, one more pass detects negative cycles.
- Parenthesisations of matrices: Catalan (1, 1, 2, 5, 14, 42 for ).