Dynamic Programming
San Skulrattanakulchai
October 19, 2018
Topics
- Recurrences
- Dynamic Programming
- bottom-up approach
- memoization (top-down approach)
- Bottom-up DP VS memoization
Recurrences
- A recurrence is a way to define a function on the (tuples of) nonnegative integers by giving two things:
- values of the function for a finite number of base cases
- values of the function for the rest of the cases in terms of values of the function on “smaller arguments”
- Example 1: The Fibonacci numbers \(f(n)\) are defined as \[
f(n) =
\left\{
\begin{array}{ll}
n, & \mbox{if $n=0$ or $n=1$} \\
f(n-1) + f(n-2), & \mbox{if $n \ge 2$}
\end{array}
\right.
\]
- Example 2: The Bionomial Coefficients \(C(n, k)\) are defined for all \(n\ge 0\) and all \(0\le k\le n\) as \[
C(n,k) =
\left\{
\begin{array}{ll}
1, & \mbox{if $k=0$ or $k=n$} \\
C(n-1,k) + C(n-1,k-1), & \mbox{otherwise}
\end{array}
\right.
\]
The problem
- Suppose a function is defined via a recurrence, and we want to write a program to evaluate the function when given its argument(s).
- As demonstrated in class, some program, if naively translated from the recurrence, is inefficient due to heavily repeated computation.
- Note. We can use the techniques of this slide to solve more problems than just function evaluation. E.g., we’ll demonstrate how to solve the Longest Common Subsequence problem in class.
Bottom-up dynamic programming
- Bottom-up dynamic programming is appropriate for solving a problem that can be described by a recurrence.
- It is a bottom-up approach.
Ideas of bottom-up dynamic programming
- Use a table to store computed values.
- We solve all problems on all smaller sizes by performing the following two steps.
- Fill in all entries of the table bottom-up using the recurrence.
- Return the desired value from the table.
Memoization
- Like bottom-up DP, it is a programming technique for evaluating a recursively-defined function efficiently.
- It works by modifying the naive translation of recurrence.
- It is a top-down approach.
Ideas of memoization
- Use a table to store previously computed values.
- Initialize the whole table to UNKNOWN VALUE except entries of the base cases, where we put in their correct values.
- 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.
Memoization VS bottom-up DP