"Dynamic programming has one of algorithms' scariest names and one of its simplest hearts: define a state, solve it once, reuse the answer. Bellman's budget-committee story is delicious color, not the entire official origin. Either way, don't let the name intimidate you."
The Name Is a Marketing Trick
Dynamic programming defines reusable states and combines their answers without repeated work. Bellman later described considerations behind the name, but that recollection should not be overstated as a single official origin story. Fibonacci memoization already demonstrates the mechanism.
The Two Conditions
A problem yields to DP when it has both of these:
- Overlapping subproblems: a naive recursion ends up solving the same smaller problems over and over (the repeated subtrees in the Fibonacci recursion tree). This is what makes caching pay off — if every subproblem were unique, there'd be nothing to reuse.
- Composable subproblems: optimization DP needs optimal substructure. Counting and recurrence-evaluation DP may not ask for an optimum at all, so verify the relevant composition law instead of forcing every DP into optimization vocabulary.
Overlapping states plus a valid recurrence make DP a strong candidate. Without overlap, memoization may add little and divide-and-conquer may be more natural. For optimization, check optimal substructure; for counting or evaluation, check the corresponding composition rule.
DP vs Divide-and-Conquer
The distinction from the last track is precise. Divide-and-conquer (merge sort) splits into subproblems that are independent — the two halves share nothing, so there's nothing to cache. Dynamic programming splits into subproblems that overlap — the same sub-answers are needed in many places, so caching them is the entire win. Same recursive instinct; the difference is whether the subproblems repeat. When they repeat, you stop recomputing and start remembering. That shift from 'recompute' to 'remember' is the whole discipline.