interviewpath
  • 0day streak
  • 10total XP
  • Level 1
0/6

Unit 1 · Algorithms · Lesson 20 of 24

Dynamic programming on sequences, grids and knapsacks

Many harder DP questions follow a few templates: two indices over two sequences, a cell in a grid, an item and a capacity, or an interval. Recognizing the template gives the state; the remaining skill is getting transitions, loop order and memory right, especially the loop direction that separates 0/1 from unbounded knapsack.
About 5 h 30 minFocus mode

Step 1: Learn the ideas

  • Two-sequence DP: LCS, edit distance, interleaving
  • Subsequence counting and pattern-matching DP
  • Grid DP and boundary handling
  • 0/1 knapsack and subset sum
  • Unbounded knapsack and coin change
  • Loop order: combinations versus ordered sequences
  • Rolling arrays and loop direction
  • Interval DP
  • Pseudo-polynomial time
  • Reconstruction from a full table

Why it matters

Once one-dimensional DP is comfortable, most harder DP questions turn out to be variations of a handful of two-dimensional templates. Interviewers use them to test whether you can generalize a recurrence, keep indices straight across two inputs, and save memory without corrupting values you still need. The templates matter beyond interviews too: edit distance and alignment underlie diffing and fuzzy matching, knapsack-style DPs appear in budgeted selection and resource allocation, and interval DPs in parsing and optimal ordering.

Core ideas

Two sequences. Let the state be a pair of prefix lengths (i, j). For longest common subsequence: if a[i-1] == b[j-1], then dp[i][j] = dp[i-1][j-1] + 1; otherwise dp[i][j] = max(dp[i-1][j], dp[i][j-1]). Edit distance uses the same table: dp[i][j] is the minimum of dp[i-1][j] + 1 (delete), dp[i][j-1] + 1 (insert) and dp[i-1][j-1] plus 0 for a match or 1 for a replacement, with base cases dp[i][0] = i and dp[0][j] = j. Prefix lengths instead of indices give a natural empty row and column and remove most off-by-one errors. Time and space are O(nm).

Grids. With right and down moves, dp[r][c] depends on the cell above and the cell to the left. Initialize the first row and column carefully: after an obstacle in the first row, every later cell in that row is unreachable. If moves can go in all four directions, dependencies form cycles and the problem is a shortest-path search, not a DP.

0/1 knapsack. dp[i][w] is the best value using the first i items with capacity w: either skip item i, giving dp[i-1][w], or take it once, giving dp[i-1][w - weight] + value. With a single array indexed by capacity, iterate w from high to low so that dp[w - weight] still holds the previous item's value when it is read; iterating upward would let the same item be taken twice. Subset sum and equal-sum partition are the boolean version.

Unbounded knapsack. Items can be reused, so dp[w] takes the best over items of dp[w - weight] + value, and the single-array loop runs upward: reading the already updated dp[w - weight] is exactly what allows reuse.

Combinations versus ordered sequences. When counting ways to reach an amount, putting the coin loop outside the amount loop counts each multiset once; putting the amount loop outside counts ordered sequences. Decide which one the problem asks for before choosing.

Interval DP. For problems such as bursting balloons or optimal parenthesization, let dp[l][r] be the best result for the interval and choose the element handled last (or the split point) inside it. Evaluate by increasing interval length so every sub-interval is ready; this is typically O(n^3).

Pseudo-polynomial time. Knapsack in O(nW) is polynomial in the numeric value W, not in the input size, since W takes only about log W bits to write. It is fast for small capacities and hopeless for capacities near 10^9; then consider a state indexed by value instead of weight, meet in the middle, or approximation.

Memory and reconstruction. Rolling two rows, or one row with the correct direction, cuts O(nm) memory to O(m). To recover an alignment or a chosen item set, keep the full table or parent choices; Hirschberg's divide-and-conquer method recovers an alignment in linear space (deep level only).

Common misconceptions

  • "0/1 and unbounded knapsack need different code." With one array, only the direction of the capacity loop differs, and that direction decides whether an item can be reused.
  • "Loop order never matters in counting DPs." Swapping the coin and amount loops switches between counting combinations and counting ordered sequences.
  • "Knapsack is polynomial." O(nW) is pseudo-polynomial; with W near 10^9 it is unusable.
  • "Edit distance needs special cases for empty strings." With prefix-length states the empty row and column are the base cases; no extra branches are needed.
  • "Every grid path problem is a DP." Only when moves create no cycles, as with right and down only; otherwise use BFS or Dijkstra.

How to approach it

Name the template first (two prefixes, a cell, an item and a capacity, an interval), then write the state in words and the case analysis on the last decision. Fill a tiny table, about 3 by 3, by hand to confirm the base cases and the direction of dependencies before coding. Compress memory only after the full table works, and say which way the loops run and why. Graduate interviews usually stop at a correct O(nm) table; mid and senior interviews more often ask for reconstruction, the memory optimization, or how the approach scales as capacities or string lengths grow.

Suggested order

  1. 1Read MIT 6.006 Lecture 16 (Dynamic Programming, Part 2: LCS, LIS, Coins) for subproblems over pairs of suffixes (the mirror image of the prefix states used in these notes) and subproblem expansion.
  2. 2Read MIT 6.006 Lecture 18 (Dynamic Programming, Part 4: Rods, Subsetsums, Pseudopolynomial) for subset sum and why its running time is pseudo-polynomial.
  3. 3Read Erickson Ch. 3 (Dynamic Programming), the edit distance and subset sum sections, and compare his recurrences with yours.
  4. 4Solve Unique Paths and Minimum Path Sum, then Longest Common Subsequence and Edit Distance, filling a 3 by 3 table by hand before coding each.
  5. 5Solve Partition Equal Subset Sum (0/1, downward loop) and Coin Change II (unbounded, upward loop) with a single array; then swap the loops in Coin Change II and explain what the new code counts.
  6. 6Solve Target Sum and Interleaving String; keep Burst Balloons and Distinct Subsequences as harder review items.

Step 2: Check off what you can do

Tap each one you can genuinely do or explain. Each earns 10 XP.

Step 3: Go deeper

  • MIT 6.006 Introduction to Algorithms (Spring 2020)Start here

    MIT OpenCourseWare

    Section: Lecture 16: Dynamic Programming, Part 2: LCS, LIS, Coins

    Two-sequence subproblems (stated on suffixes) and subproblem expansion; Lecture 18 on the same index covers subset sum and pseudo-polynomial time.

    Open(opens in a new tab)Link responded, 5 Oct 2026
  • Competitive Programmer’s HandbookStart here

    CSES

    Section: Ch. 7: Dynamic programming

    Compact treatment of grid paths, knapsack problems and edit distance with implementation details.

    Open(opens in a new tab)Link responded, 5 Oct 2026
  • Algorithms (Jeff Erickson) with companion lecture notes

    Jeff Erickson, University of Illinois Urbana-Champaign

    Section: Ch. 3: Dynamic Programming

    Careful derivations of edit distance, subset sum and longest increasing subsequence recurrences, with attention to evaluation order.

    Open(opens in a new tab)Link responded, 5 Oct 2026

Step 4: Practice

Name the template and write the state in words before coding. For every knapsack-style problem, write the full two-dimensional version first, then compress to one array and justify the loop direction aloud. Keep Burst Balloons and Distinct Subsequences for review rotation once the core templates feel routine.

Record attempts on each problem’s page (+15 XP, +10 more when solved on your own).

Step 5: Test yourself

Answer each one out loud or on paper before you finish the lesson.

  1. Question 1What do i and j mean in your LCS table, and why are prefix lengths easier than indices?
  2. Question 2Which loop order counts combinations of coins, and which counts ordered sequences?
  3. Question 3Why does an obstacle in the first row affect every later cell in that row?
  4. Question 4In what order must an interval DP be evaluated, and why?
  5. Question 5What information is lost when you compress the table to one row?
  6. Question 6When is a grid path problem not a DP?

You’re done when you can

  • Derive the edit distance recurrence and base cases from scratch in under five minutes.
  • Explain with a two-item example why the capacity loop runs downward for 0/1 knapsack and upward for unbounded knapsack.
  • Solve one unseen two-sequence or knapsack problem in under 35 minutes, including a one-row memory optimization.
  • Explain why O(nW) is pseudo-polynomial and what you would do when W is very large.

Finish the lesson

How confident do you feel?

Lesson complete!

+50 XP

Reviews will come up on the Practice tab so it sticks.

Your notes and study time

Log study time