"When a problem juggles two axes—two strings, or items plus a budget—the state becomes a grid. Edit distance and LCS are foundational workers under spell suggestions, diffs, and DNA alignment. The whole product is rarely this one table, but plenty of it stands on the table."
Two Dimensions of State
A 2D DP has a subproblem identified by a pair of numbers, so the table is a grid. The most common shape: two sequences, where dp[i][j] answers a question about 'the first i of sequence A and the first j of sequence B.' Another: dp[i][w] = 'using the first i items within budget w.' Each cell is computed from its neighbors — usually the cell above, the cell to the left, and/or the diagonal — and you fill the grid in an order (typically row by row) that guarantees those neighbors are ready before you need them.
Edit Distance: the Canonical 2D DP
The edit distance (Levenshtein distance) between two strings is the minimum number of single-character insertions, deletions, or substitutions to turn one into the other. Define dp[i][j] = the edit distance between the first i characters of A and the first j of B. The recurrence reads like a decision: if the current characters match, dp[i][j] = dp[i-1][j-1] (no edit needed); otherwise it's 1 + min of three choices — delete (dp[i-1][j]), insert (dp[i][j-1]), or substitute (dp[i-1][j-1]). Three neighbors, one min. The base cases (turning a string into the empty string costs its length) seed the first row and column.
Where 2D DPs Run the World
Edit distance and LCS are important foundations for fuzzy matching, diffing, and biological sequence comparison. Production tools may instead or additionally use Myers diff, tokenization, heuristics, and domain-specific scoring. Likewise, knapsack is a useful model for some allocation problems, not the universal engine behind them.
Pippa's Confession
dp[3][2] is 'the cost to turn the first 3 letters of A into the first 2 letters of B.' Once each cell had a sentence, the three-way min stopped being a formula and became three obvious choices — delete, insert, or substitute. The trick that unlocked every 2D DP for me was refusing to write a recurrence until I could say, in plain words, exactly what dp[i][j] represents.