Title: Dynamic Programming
1Dynamic Programming
2When to Use DP
- Usually used to solve Optimization problems
- Usually the problem can be formulated as
recursion - The solution of a problem is made up the
solutions of its sub-problems and sub-problems
overlaps
3E.g. Fibonacci Number
- The problem (Background)
- Every mature pair of rabbit give birth to a pair
of rabbits in every month - Newly born rabbits become mature after one month
- There is one pair of rabbit at beginning of a
year, how many pairs are there after one year? - Formulation
- f(n) f(n-1) f(n-2)
- f(1) 1, f(2) 2
4FN Naïve Solution
int f (int n) int r if (nlt2) r n
else r f(n-1) f(n-2) return r
f(6)
-------------------------
f(5)
f(4)
---------------- ------------
f(4) f(3) f(3)
f(2)
------------ -------
-------
f(3) f(2) f(2) f(1) f(2) f(1)
-------- f(2) f(1)
5FN Memoization
- Memorize whatever calculated, calculate only once
/ Memoization Method. Assume n is at most 100
long mem101 memset(mem, 0, sizeof(mem))
/ int f (int n) int r if (memn gt 0)
return memn if (n lt 2) r n else r
f(n-1) f(n-2) memn r return r
6Turn Recursion into Memoization
- Initialize memory in main function
- int f ()
- if already calculated return the result
- calculate the result using recursion
- save the result in memory
- return the result
7FN Fill-in-the-table method
- Bottom up approach
- Figure out the order in which the memory is
filled in manually, fill in the table using loop
long mem101 int f (int n) int i
mem1 1 mem2 2 for (i 3 i lt n
i) memi memi-1 memi-2
return memn
8FN Save Memory
- Only previous two results are needed in every
step, so just keep these two result
int f (int n) int pre_2, pre_1, cur, i
if (n lt 2) return n pre_2 1 pre_1 2
for (i 3 i lt n i) cur p_1
p_2 p_1 cur p_2 p_1 return
cur
9E.g. Longest Common Subsequence
- A subsequence is a sequence resulting from
deleting a few items in original sequence - bdfk is a subsequence of abcdefghijklmn
- Given two strings find the longest common
subsequence - adf is common subsequence of abdfg and
adgfkg - adfg is another
10LCS Formulation
- A a1a2a3am B b1b2b3bn
- Ai a1a2a3ai Bj b1b2b3bj
- f (i, j) is the length of longest common
subsequence of Ai and Bj - f (i, j) 1 f (i-1, j-1) if ai bj
- f (i, j) max (f(i-1,j), f(i, j-1))
- f (0, j) 0
- f (i, 0) 0
11LCS memoization
char a1001, b10001 / the two sequence
/ int mem10011001 / the memory
/ memset(mem, -1, sizeof(mem)) / do it in main
method / int f (int i, int j) int r
if (memij gt 0) return memij if (i
0 j 0) r 0 else if (ai bj)
r 1 f (i-1, j-1) else r max(f(i-1, j),
f(I, j-1)) memij r return r
12LCS Fill-in-the-Table
- F(i, j) depends only on three previous result
- f (i-1, j) is the same column on previous row
- f (i, j-1) is the previous column on same row
- f (i-1, j-1) is the previous column on previous
row - We can fill in the mem table row by row
- 0th row are all zeros
- 0th column are all zeros
- fill in memij by comparing ai,bj and base
on the value of memi-1j and memij-1
13LCS save the memory
- Only two rows are needed the current row and
the previous row. - Fill in current row base on previous row
- Rotate the role of current and previous row
14LCS Find the Common Subsequnce
- By using another table dij
- dij 0 if memij is calculated base on
memi-1j - dij 1 if memij is from memij-1
- dij 2 if memij is from memi-1j-1
- Construct the sequence using a recursion start at
dmn and follow the directory recorded until
reach d0j or di0 - TODO a diagram
15E.g. Longest Run on a Snowboard
16LRS Recursion
- Let f (i, j) be the length of longest run start
at location (i,j) - Let h (i, j) be the height of location
- f (i, j) 1 max (f values of reachable
neighbors) - Starting from the highest locations
17LCS Fill-in-the-Table
- Sort location (i,j) according to h(i, j) in
increasing order - Fill in f (i, j) in order based on the value of f
(i-1, j), f(i1, j), f(i, j-1), f(i, j1)