Dynamic programming, and why it is the same as an EV recursion
CS · Chapter 614 min readAsked at Hudson River Trading, Jump, Jane Street, Citadel Securities
After this lesson you should be able to
- Identify the state and transition of a dynamic programme.
- Convert a recursion into either memoisation or a table, and say which fits.
- Recognise that a probability brainteaser and a DP problem are the same object.
Dynamic programming is recursion with the repeated work removed. The hard part is never the code — it is choosing the state. And once you see that an expected-value recursion is a dynamic programme over the same state space, half the probability questions in a trading interview become coding questions you already know how to do.
Proposition 6.1
The four questions
Every dynamic programme answers the same four questions, and answering them aloud in order is most of the interview. What is the state? What is the transition? What are the base cases? In what order can the states be evaluated so that each one’s dependencies are already computed?
Holds when
- If the state is right, the transition is usually one line.
- If you cannot find an ordering, the problem may need memoisation on a graph rather than a table — or it may have a cycle, in which case it is a linear system, not a DP.
| Aspect | Memoisation (top-down) | Tabulation (bottom-up) |
|---|---|---|
| Written as | The natural recursion plus a cache | Loops filling an array |
| Visits | Only reachable states | Every state in the table |
| Risk | Stack depth on deep recursions | Computing states you never needed |
| Space | Hard to reduce below the full state space | Often reducible to one or two rows |
| Best when | The state space is sparse or awkward to order | The state space is dense and the order is obvious |
from functools import cache
def climb_memo(n: int) -> int:
"""Ways to climb n stairs taking 1 or 2 at a time."""
@cache
def f(k: int) -> int:
if k < 0:
return 0
if k == 0:
return 1
return f(k - 1) + f(k - 2)
return f(n)
def climb_table(n: int) -> int:
prev, cur = 1, 1 # f(0), f(1)
for _ in range(2, n + 1):
prev, cur = cur, cur + prev
return cur # O(n) time, O(1) spaceThe rest of this lesson is in Premium
You have read the opening. 11 more sections follow, including 4 worked examples and 3 quick checks.
Nothing is charged for 7 days, and you can cancel before then. Or read Complexity: reading it off, and deriving it in full, free.