1 / 17

Dynamic Programming

Dynamic Programming. Andrew Lim Zhu Wenbin. When 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. E.g. Fibonacci Number.

galia
Download Presentation

Dynamic Programming

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Dynamic Programming Andrew Lim Zhu Wenbin

  2. When 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

  3. E.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

  4. FN Naïve Solution int f (int n) { int r; if (n<=2) 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)

  5. FN: Memoization • Memorize whatever calculated, calculate only once /* Memoization Method. Assume n is at most 100 * long mem[101]; * memset(mem, 0, sizeof(mem)); */ int f (int n) { int r; if (mem[n] > 0) return mem[n]; if (n <= 2) r = n; else r = f(n-1) + f(n-2); mem[n] = r; return r; }

  6. Turn 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 }

  7. FN: 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 mem[101]; int f (int n) { int i; mem[1] = 1; mem[2] = 2; for (i = 3; i <= n; i++) mem[i] = mem[i-1] + mem[i-2]; return mem[n]; }

  8. FN: 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 <= 2) return n; pre_2 = 1; pre_1 = 2; for (i = 3; i <= n; i++) { cur = p_1 + p_2; p_1 = cur; p_2 = p_1; } return cur; }

  9. E.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

  10. LCS: Formulation • A = a1a2a3…am B = b1b2b3…bn • Ai = a1a2a3…ai Bj = b1b2b3…bj • 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

  11. LCS: memoization char a[1001], b[10001]; /* the two sequence */ int mem[1001][1001]; /* the memory */ memset(mem, -1, sizeof(mem)); /* do it in main method */ int f (int i, int j) { int r; if (mem[i][j] >= 0) return mem[i][j]; if (i == 0 || j == 0) r = 0; else if (a[i] == b[j]) r = 1 + f (i-1, j-1); else r = max(f(i-1, j), f(I, j-1)); mem[i][j] = r; return r; }

  12. LCS: 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 mem[i][j] by comparing a[i],b[j] and base on the value of mem[i-1][j] and mem[i][j-1]

  13. LCS: 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

  14. LCS: Find the Common Subsequnce • By using another table d[i][j] • d[i][j] = 0 if mem[i][j] is calculated base on mem[i-1][j] • d[i][j] = 1 if mem[i][j] is from mem[i][j-1] • d[i][j] = 2 if mem[i][j] is from mem[i-1][j-1] • Construct the sequence using a recursion start at d[m][n] and follow the directory recorded until reach d[0][j] or d[i][0] • TODO: a diagram

  15. E.g. Longest Run on a Snowboard

  16. LRS: 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

  17. LCS: 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(i+1, j), f(i, j-1), f(i, j+1)

More Related