A recurrence is a way to define a function on the (tuples of) nonnegative integers by giving two things:
Example: the Fibonacci numbers are defined as
f(0) = 0, f(1) = 1, and f(n) = f(n-1) + f(n-2) if n > 1.
As demonstrated in class, naively implementing the recurrence gives an inefficient algorithm because of repeated computation.
Memoization is a technique for writing efficient programs to solve a recurrence whose definition gives an inefficient algorithm if implemented top-down.
Ideas of Memoization
Use a table to store previously computed values.
Initialize the whole table to UNKNOWN VALUE.
Each time a value is computed and known, immediately store it into the table.
Any time a value is needed, check first whether it is already stored in the table. If it is, use it; otherwise, compute its value.
To compute the value of the function on any argument, use the recurrence and the above two ideas.
Like memoization, dynamic programming is appropriate for solving a problem that can be described by a recurrence.
Ideas of Dynamic Programming
To solve a problem by dynamic programming, perform the following two steps.
. | Memoization | Bottom-up DP |
---|---|---|
Implementation of Recurrence | top-down | bottom-up |
Initialization of Table | required | not required |
# Table Entries Computed | partial | complete |
Space-saving Improvement | not possible | possible |