Matrix Chain Multiplication
Suppose you're organizing a road trip with multiple legs. The order you combine those legs doesn't change your final destination — but it can make a huge difference in how much fuel you burn. Matrix chain multiplication is exactly like this: no matter how you parenthesize A × B × C × D, the result is the same matrix. But the cost — the number of arithmetic operations — can vary by orders of magnitude.
Multiplying a (a×b) matrix by a (b×c) matrix costs a × b × c scalar multiplications and produces an (a×c) result.
A Concrete Example
Three matrices: A(10×30), B(30×5), C(5×60).
(A×B)×C: A×B costs 10×30×5 = 1,500 → (10×5); then ×C costs 10×5×60 = 3,000. Total: 4,500.
A×(B×C): B×C costs 30×5×60 = 9,000 → (30×60); then A× costs 10×30×60 = 18,000. Total: 27,000.
The first order is 6× cheaper! For longer chains, the gap grows much larger.
The DP State
Define dp[i][j] = minimum scalar multiplications to compute the product of matrices i through j. Dimensions are given as an array dim[] where matrix i has shape dim[i-1] × dim[i]. We want dp[1][n].
The Recurrence
For any split point k (i ≤ k < j), we first compute matrices i..k, then k+1..j, then multiply the two results:
dp[i][j] = min over k of: dp[i][k] + dp[k+1][j] + dim[i-1] × dim[k] × dim[j]
Base case: dp[i][i] = 0 (a single matrix needs no multiplication).
Fill Order: Short Chains First
dp[i][j] needs dp[i][k] and dp[k+1][j] — both shorter chains. This is a classic case of Interval DP. So fill by increasing chain length: l = 1 (base cases), then l = 2 (pairs), up to l = n. For each length, iterate over all valid starting positions i (with j = i + l - 1).
Recovering the Optimal Parenthesization
Store the best split point s[i][j] alongside dp[i][j]. Then recursively read the parenthesization: s[1][n] gives the top-level split; recurse into [1, s[1][n]] and [s[1][n]+1, n].