Fibonacci as a Dynamic Programming Example
The Fibonacci recurrence is
Naive recursion expands the same subproblems repeatedly and takes exponential time. Memoization reduces the reachable states to ; bottom-up evaluation makes their dependency order explicit.
def fibonacci(n: int) -> int:
if n < 0:
raise ValueError("n must be non-negative")
previous, current = 0, 1
for _ in range(n):
previous, current = current, previous + current
return previous
State compression
To compute , a table would retain every value from through . The transition reads only the previous two, so two variables are sufficient:
- time: arithmetic operations;
- auxiliary state: machine words;
- integer bit size still grows with , so bit-complexity is not constant per addition for very large indices.
What the example teaches
Fibonacci is useful for recognizing overlapping subproblems and safe memory compression, but it is not a representative optimization problem. Faster doubling or matrix methods compute with recurrence depth by using additional algebraic structure.
Avoid a mutable default dictionary in memoized Python examples; cache ownership and lifetime should be explicit.