cpsc 490 problem solving in computer science
play

CPSC 490: Problem Solving in Computer Science Assignment 3 is due - PowerPoint PPT Presentation

Lecture 8: Dynamic programming Henry Xia, Brandon Zhang based on CPSC 490 slides from 2014-2018 2019-01-28 University of British Columbia CPSC 490: Problem Solving in Computer Science Assignment 3 is due Friday, Feb 1 at 8 pm.


  1. Lecture 8: Dynamic programming Henry Xia, Brandon Zhang based on CPSC 490 slides from 2014-2018 2019-01-28 University of British Columbia CPSC 490: Problem Solving in Computer Science

  2. • Assignment 3 is due Friday, Feb 1 at 8 pm. • Presentation topics have been posted. 1 Announcements

  3. 2. Find the recurrence relation (the transitions) • We can’t solve it if we have circular dependencies! 2 time to compute one state states Runtime of DP algorithm: O f n in order f 2 • Iterative DP (bottom-up): instead of recursion, compute f 1 f k if we already did • Memoization (top-down): implement the function using recursion, but do not recompute 3. Optimize by reusing previously computed values • f 1 2 f n 1 function of f n • f n Solving a problem with DP involves these three steps: What is dynamic programming? DP algorithm = recursive function 1. Characterize the problem and subproblems by a state • Suppose we can represent the answer to the problem as f ( n ) . . . • Then, can we use f ( n − 1 ) , f ( n − 2 ) , . . . to quickly compute f ( n ) ?

  4. 2 • Memoization (top-down): implement the function using recursion, but do not recompute time to compute one state states Runtime of DP algorithm: O f n in order f 2 • Iterative DP (bottom-up): instead of recursion, compute f 1 f k if we already did 3. Optimize by reusing previously computed values Solving a problem with DP involves these three steps: What is dynamic programming? DP algorithm = recursive function 1. Characterize the problem and subproblems by a state • Suppose we can represent the answer to the problem as f ( n ) . . . • Then, can we use f ( n − 1 ) , f ( n − 2 ) , . . . to quickly compute f ( n ) ? 2. Find the recurrence relation (the transitions) • f ( n ) = function of f ( n − 1 ) , f ( n − 2 ) , . . . • f ( 1 ) = . . . • We can’t solve it if we have circular dependencies!

  5. 3. Optimize by reusing previously computed values Solving a problem with DP involves these three steps: • Memoization (top-down): implement the function using recursion, but do not recompute 2 What is dynamic programming? DP algorithm = recursive function 1. Characterize the problem and subproblems by a state • Suppose we can represent the answer to the problem as f ( n ) . . . • Then, can we use f ( n − 1 ) , f ( n − 2 ) , . . . to quickly compute f ( n ) ? 2. Find the recurrence relation (the transitions) • f ( n ) = function of f ( n − 1 ) , f ( n − 2 ) , . . . • f ( 1 ) = . . . • We can’t solve it if we have circular dependencies! f ( k ) if we already did • Iterative DP (bottom-up): instead of recursion, compute f ( 1 ) , f ( 2 ) , . . . , f ( n ) in order Runtime of DP algorithm: O (# states × time to compute one state )

  6. 3 Example 1 – Tiling How many ways are there to tile a 2 × n grid with 2 × 1 tiles?

  7. observe these two cases: 4 Example 1 – Solution DP state: f ( k ) = number of ways to tile 2 × k grid with 2 × 1 tiles. Base case: f ( 0 ) = f ( 1 ) = 1. To compute f ( k ) we consider what possible “last” tiles we use to tile the 2 × k grid and

  8. 5 Example 1 – Solution Recurrence: f ( k ) = f ( k − 1 ) + f ( k − 2 ) Answer: f ( n ) Time complexity: O ( n )

  9. 6 7 1 4 2 3 3 2 4 1 5 Bottom-up 6 Top-down Example 1 – Implementation memo = array of size N, initialized to null def f(k): if k == 0 or k == 1: return 1 if memo[k] is not null: return memo[k] ans = f(k-1) + f(k-2) memo[k] = ans return ans f = array of size N f[0] = f[1] = 1 for i = 2 .. n: f[i] = f[i-1] + f[i-2]

  10. Top-down • Advantages: oħten easier to write, can be faster if the state space is sparse • Disadvantages: uses recursion, which can be slow Bottom-up • Advantages: avoids recursion, can apply memory-saving tricks • Disadvantages: need to figure out the correct order in which to compute states 7 Top-down vs. bottom-up

  11. Top-down • Advantages: oħten easier to write, can be faster if the state space is sparse • Disadvantages: uses recursion, which can be slow Bottom-up • Advantages: avoids recursion, can apply memory-saving tricks • Disadvantages: need to figure out the correct order in which to compute states 7 Top-down vs. bottom-up

  12. Find the length of the longest increasing subsequence (LIS) in an array of n integers. 8 Example 2 – Longest increasing subsequence [10, 11, 1, 5, 3, 9, -1, 7, 25]

  13. Base case: f 0 1. To get LIS ending at the A k we take the element A k and append it to a LIS ending at a previous smaller element A i . Here’s an example when considering the element 7. 9 Example 2 – Solution 1 DP state: f ( k ) = length of the LIS of A [ 1 . . . k ] ending at A [ k ] .

  14. To get LIS ending at the A k we take the element A k and append it to a LIS ending at a previous smaller element A i . Here’s an example when considering the element 7. 9 Example 2 – Solution 1 DP state: f ( k ) = length of the LIS of A [ 1 . . . k ] ending at A [ k ] . Base case: f ( 0 ) = 1.

  15. [10, 11, 1, 5, 3, 9, -1, 7, 25] Here’s an example when considering the element 7. 9 Example 2 – Solution 1 DP state: f ( k ) = length of the LIS of A [ 1 . . . k ] ending at A [ k ] . Base case: f ( 0 ) = 1. To get LIS ending at the A [ k ] we take the element A [ k ] and append it to a LIS ending at a previous smaller element A [ i ] . We can’t take this since 10 > 7

  16. [10, 11, 1, 5, 3, 9, -1, 7, 25] Here’s an example when considering the element 7. 9 Example 2 – Solution 1 DP state: f ( k ) = length of the LIS of A [ 1 . . . k ] ending at A [ k ] . Base case: f ( 0 ) = 1. To get LIS ending at the A [ k ] we take the element A [ k ] and append it to a LIS ending at a previous smaller element A [ i ] . We can’t take this since 11 > 7

  17. Here’s an example when considering the element 7. 9 Example 2 – Solution 1 DP state: f ( k ) = length of the LIS of A [ 1 . . . k ] ending at A [ k ] . Base case: f ( 0 ) = 1. To get LIS ending at the A [ k ] we take the element A [ k ] and append it to a LIS ending at a previous smaller element A [ i ] . [10, 11, 1, 5, 3, 9, -1, 7, 25]

  18. Here’s an example when considering the element 7. 9 Example 2 – Solution 1 DP state: f ( k ) = length of the LIS of A [ 1 . . . k ] ending at A [ k ] . Base case: f ( 0 ) = 1. To get LIS ending at the A [ k ] we take the element A [ k ] and append it to a LIS ending at a previous smaller element A [ i ] . [10, 11, 1, 5, 3, 9, -1, 7, 25]

  19. Here’s an example when considering the element 7. 9 Example 2 – Solution 1 DP state: f ( k ) = length of the LIS of A [ 1 . . . k ] ending at A [ k ] . Base case: f ( 0 ) = 1. To get LIS ending at the A [ k ] we take the element A [ k ] and append it to a LIS ending at a previous smaller element A [ i ] . [10, 11, 1, 5, 3, 9, -1, 7, 25]

  20. 9 Here’s an example when considering the element 7. Example 2 – Solution 1 DP state: f ( k ) = length of the LIS of A [ 1 . . . k ] ending at A [ k ] . Base case: f ( 0 ) = 1. To get LIS ending at the A [ k ] we take the element A [ k ] and append it to a LIS ending at a previous smaller element A [ i ] . [10, 11, 1, 5, 3, 9, -1, 7, 25] We can’t take this since 9 > 7

  21. Here’s an example when considering the element 7. 9 Example 2 – Solution 1 DP state: f ( k ) = length of the LIS of A [ 1 . . . k ] ending at A [ k ] . Base case: f ( 0 ) = 1. To get LIS ending at the A [ k ] we take the element A [ k ] and append it to a LIS ending at a previous smaller element A [ i ] . [10, 11, 1, 5, 3, 9, -1, 7, 25]

  22. Here’s an example when considering the element 7. 9 Example 2 – Solution 1 DP state: f ( k ) = length of the LIS of A [ 1 . . . k ] ending at A [ k ] . Base case: f ( 0 ) = 1. To get LIS ending at the A [ k ] we take the element A [ k ] and append it to a LIS ending at a previous smaller element A [ i ] . Recurrence: f ( k ) = 1 + max f ( i ) where 0 ≤ i < k and A [ i ] < A [ k ] Answer: max f ( k ) where 0 ≤ k ≤ n Time complexity: O ( n 2 )

  23. Here’s an example when considering the element 7. Can we do better? 9 Example 2 – Solution 1 DP state: f ( k ) = length of the LIS of A [ 1 . . . k ] ending at A [ k ] . Base case: f ( 0 ) = 1. To get LIS ending at the A [ k ] we take the element A [ k ] and append it to a LIS ending at a previous smaller element A [ i ] . Recurrence: f ( k ) = 1 + max f ( i ) where 0 ≤ i < k and A [ i ] < A [ k ] Answer: max f ( k ) where 0 ≤ k ≤ n Time complexity: O ( n 2 )

  24. 10 Flip the DP state We had f ( k ) = i , why not do L ( i ) = k instead? Instead of f ( k ) = length of LIS ending at index k we’ll try L ( i ) = smallest element ending a LIS of length i

  25. Time complexity: O n 2 . Still the same! 11 L i j But, we can speed this version up... . Answer: the maximum i such that L i n otherwise 1 L i j 1 A j 1 1 j if L i A j L i j Recurrence relation: we consider adding on the current number to all previous LISes. , L 0 j Base case: L i 0 such element). Example 2 – Solution attempt DP state: L ( i , j ) = smallest element ending LIS of length i in A [ 1 . . . j ] (or ∞ if there is no

Recommend


More recommend