# 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:
1. values of the function for a finite number of base cases
2. 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.
1. Fill in all entries of the table bottom-up using the recurrence.
2. Return the desired value from the desired table entry.

# 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

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