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

cpsc 490 problem solving in computer science
SMART_READER_LITE
LIVE PREVIEW

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.


slide-1
SLIDE 1

CPSC 490: Problem Solving in Computer Science

Lecture 8: Dynamic programming

Henry Xia, Brandon Zhang

based on CPSC 490 slides from 2014-2018

2019-01-28

University of British Columbia

slide-2
SLIDE 2

Announcements

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

1

slide-3
SLIDE 3

What is dynamic programming?

DP algorithm = recursive function Solving a problem with DP involves these three steps:

  • 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!
  • 3. Optimize by reusing previously computed values
  • Memoization (top-down): implement the function using recursion, but do not recompute

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

2

slide-4
SLIDE 4

What is dynamic programming?

DP algorithm = recursive function Solving a problem with DP involves these three steps:

  • 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!
  • 3. Optimize by reusing previously computed values
  • Memoization (top-down): implement the function using recursion, but do not recompute

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

2

slide-5
SLIDE 5

What is dynamic programming?

DP algorithm = recursive function Solving a problem with DP involves these three steps:

  • 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!
  • 3. Optimize by reusing previously computed values
  • Memoization (top-down): implement the function using recursion, but do not recompute

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)

2

slide-6
SLIDE 6

Example 1 – Tiling

How many ways are there to tile a 2 × n grid with 2 × 1 tiles?

3

slide-7
SLIDE 7

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

  • bserve these two cases:

4

slide-8
SLIDE 8

Example 1 – Solution

Recurrence: f(k) = f(k − 1) + f(k − 2) Answer: f(n) Time complexity: O(n)

5

slide-9
SLIDE 9

Example 1 – Implementation

Top-down

1

memo = array of size N, initialized to null

2

def f(k):

3

if k == 0 or k == 1: return 1

4

if memo[k] is not null: return memo[k]

5

ans = f(k-1) + f(k-2)

6

memo[k] = ans

7

return ans

Bottom-up

1

f = array of size N

2

f[0] = f[1] = 1

3

for i = 2 .. n:

4

f[i] = f[i-1] + f[i-2]

6

slide-10
SLIDE 10

Top-down vs. bottom-up

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

slide-11
SLIDE 11

Top-down vs. bottom-up

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

slide-12
SLIDE 12

Example 2 – Longest increasing subsequence

Find the length of the longest increasing subsequence (LIS) in an array of n integers.

[10, 11, 1, 5, 3, 9, -1, 7, 25]

8

slide-13
SLIDE 13

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 . Here’s an example when considering the element 7.

9

slide-14
SLIDE 14

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 . Here’s an example when considering the element 7.

9

slide-15
SLIDE 15

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]. Here’s an example when considering the element 7.

[10, 11, 1, 5, 3, 9, -1, 7, 25] We can’t take this since 10 > 7

9

slide-16
SLIDE 16

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]. Here’s an example when considering the element 7.

[10, 11, 1, 5, 3, 9, -1, 7, 25] We can’t take this since 11 > 7

9

slide-17
SLIDE 17

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]. Here’s an example when considering the element 7.

[10, 11, 1, 5, 3, 9, -1, 7, 25]

9

slide-18
SLIDE 18

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]. Here’s an example when considering the element 7.

[10, 11, 1, 5, 3, 9, -1, 7, 25]

9

slide-19
SLIDE 19

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]. Here’s an example when considering the element 7.

[10, 11, 1, 5, 3, 9, -1, 7, 25]

9

slide-20
SLIDE 20

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]. Here’s an example when considering the element 7.

[10, 11, 1, 5, 3, 9, -1, 7, 25] We can’t take this since 9 > 7

9

slide-21
SLIDE 21

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]. Here’s an example when considering the element 7.

[10, 11, 1, 5, 3, 9, -1, 7, 25]

9

slide-22
SLIDE 22

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]. Here’s an example when considering the element 7. 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(n2)

9

slide-23
SLIDE 23

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]. Here’s an example when considering the element 7. 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(n2)

Can we do better?

9

slide-24
SLIDE 24

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

10

slide-25
SLIDE 25

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 such element). Base case: L i 0 , L 0 j Recurrence relation: we consider adding on the current number to all previous LISes. L i j A j if L i 1 j 1 A j L i j 1 L i j 1

  • therwise

Answer: the maximum i such that L i n . Time complexity: O n2 . Still the same! But, we can speed this version up...

11

slide-26
SLIDE 26

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 such element). Base case: L(i, 0) = ∞, L(0, j) = −∞ Recurrence relation: we consider adding on the current number to all previous LISes. L i j A j if L i 1 j 1 A j L i j 1 L i j 1

  • therwise

Answer: the maximum i such that L i n . Time complexity: O n2 . Still the same! But, we can speed this version up...

11

slide-27
SLIDE 27

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 such element). Base case: L(i, 0) = ∞, L(0, j) = −∞ Recurrence relation: we consider adding on the current number to all previous LISes. L(i, j) = { A[j] if L(i − 1, j − 1) < A[j] < L(i, j − 1) L(i, j − 1)

  • therwise

Answer: the maximum i such that L i n . Time complexity: O n2 . Still the same! But, we can speed this version up...

11

slide-28
SLIDE 28

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 such element). Base case: L(i, 0) = ∞, L(0, j) = −∞ Recurrence relation: we consider adding on the current number to all previous LISes. L(i, j) = { A[j] if L(i − 1, j − 1) < A[j] < L(i, j − 1) L(i, j − 1)

  • therwise

Answer: the maximum i such that L(i, n) < ∞. Time complexity: O n2 . Still the same! But, we can speed this version up...

11

slide-29
SLIDE 29

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 such element). Base case: L(i, 0) = ∞, L(0, j) = −∞ Recurrence relation: we consider adding on the current number to all previous LISes. L(i, j) = { A[j] if L(i − 1, j − 1) < A[j] < L(i, j − 1) L(i, j − 1)

  • therwise

Answer: the maximum i such that L(i, n) < ∞. Time complexity: O(n2). Still the same! But, we can speed this version up...

11

slide-30
SLIDE 30

Example 2 – Solution 2

First, observe that at most one element of each row changes (as we go from L(i, j) to L(i, j + 1)). Let’s throw away the second parameter and update the table as we go! DP state: L i smallest element ending LIS of length i (or if there is no such element). Base case: initialize L i to for all i Suppose our DP state L is valid for the subarray A 1 k 1 , and we encounter a new element A k . How do we update L? Observation 1: L is monotonically increasing Observation 2: only need to update the first element A k to A k We can binary search to find this element to update! Answer: the biggest i such that L i Time complexity: O n n

12

slide-31
SLIDE 31

Example 2 – Solution 2

First, observe that at most one element of each row changes (as we go from L(i, j) to L(i, j + 1)). Let’s throw away the second parameter and update the table as we go! DP state: L(i) = smallest element ending LIS of length i (or ∞ if there is no such element). Base case: initialize L i to for all i Suppose our DP state L is valid for the subarray A 1 k 1 , and we encounter a new element A k . How do we update L? Observation 1: L is monotonically increasing Observation 2: only need to update the first element A k to A k We can binary search to find this element to update! Answer: the biggest i such that L i Time complexity: O n n

12

slide-32
SLIDE 32

Example 2 – Solution 2

First, observe that at most one element of each row changes (as we go from L(i, j) to L(i, j + 1)). Let’s throw away the second parameter and update the table as we go! DP state: L(i) = smallest element ending LIS of length i (or ∞ if there is no such element). Base case: initialize L(i) to ∞ for all i Suppose our DP state L is valid for the subarray A 1 k 1 , and we encounter a new element A k . How do we update L? Observation 1: L is monotonically increasing Observation 2: only need to update the first element A k to A k We can binary search to find this element to update! Answer: the biggest i such that L i Time complexity: O n n

12

slide-33
SLIDE 33

Example 2 – Solution 2

First, observe that at most one element of each row changes (as we go from L(i, j) to L(i, j + 1)). Let’s throw away the second parameter and update the table as we go! DP state: L(i) = smallest element ending LIS of length i (or ∞ if there is no such element). Base case: initialize L(i) to ∞ for all i Suppose our DP state L is valid for the subarray A[1..k − 1], and we encounter a new element A[k]. How do we update L? Observation 1: L is monotonically increasing Observation 2: only need to update the first element A k to A k We can binary search to find this element to update! Answer: the biggest i such that L i Time complexity: O n n

12

slide-34
SLIDE 34

Example 2 – Solution 2

First, observe that at most one element of each row changes (as we go from L(i, j) to L(i, j + 1)). Let’s throw away the second parameter and update the table as we go! DP state: L(i) = smallest element ending LIS of length i (or ∞ if there is no such element). Base case: initialize L(i) to ∞ for all i Suppose our DP state L is valid for the subarray A[1..k − 1], and we encounter a new element A[k]. How do we update L? Observation 1: L is monotonically increasing Observation 2: only need to update the first element A k to A k We can binary search to find this element to update! Answer: the biggest i such that L i Time complexity: O n n

12

slide-35
SLIDE 35

Example 2 – Solution 2

First, observe that at most one element of each row changes (as we go from L(i, j) to L(i, j + 1)). Let’s throw away the second parameter and update the table as we go! DP state: L(i) = smallest element ending LIS of length i (or ∞ if there is no such element). Base case: initialize L(i) to ∞ for all i Suppose our DP state L is valid for the subarray A[1..k − 1], and we encounter a new element A[k]. How do we update L? Observation 1: L is monotonically increasing Observation 2: only need to update the first element > A[k] to A[k] We can binary search to find this element to update! Answer: the biggest i such that L i Time complexity: O n n

12

slide-36
SLIDE 36

Example 2 – Solution 2

First, observe that at most one element of each row changes (as we go from L(i, j) to L(i, j + 1)). Let’s throw away the second parameter and update the table as we go! DP state: L(i) = smallest element ending LIS of length i (or ∞ if there is no such element). Base case: initialize L(i) to ∞ for all i Suppose our DP state L is valid for the subarray A[1..k − 1], and we encounter a new element A[k]. How do we update L? Observation 1: L is monotonically increasing Observation 2: only need to update the first element > A[k] to A[k] We can binary search to find this element to update! Answer: the biggest i such that L i Time complexity: O n n

12

slide-37
SLIDE 37

Example 2 – Solution 2

First, observe that at most one element of each row changes (as we go from L(i, j) to L(i, j + 1)). Let’s throw away the second parameter and update the table as we go! DP state: L(i) = smallest element ending LIS of length i (or ∞ if there is no such element). Base case: initialize L(i) to ∞ for all i Suppose our DP state L is valid for the subarray A[1..k − 1], and we encounter a new element A[k]. How do we update L? Observation 1: L is monotonically increasing Observation 2: only need to update the first element > A[k] to A[k] We can binary search to find this element to update! Answer: the biggest i such that L(i) < ∞ Time complexity: O(n log n)

12

slide-38
SLIDE 38

Example 3 – Knapsack

You have n items, each with weight wi and value vi You can carry maximum weight W Maximize total value you can carry, taking at most one of each item. Value (v) 1 10 3 7 Weight (w) 1 9 2 3 If W = 9 then we can get value 11 by taking the 1st, 3rd, and 4th items.

13

slide-39
SLIDE 39

Example 3 – Solution

DP state: f(n, k) = Maximum value of items that can be placed in the knapsack from items {1, 2, . . . , n} given capacity k. Base case: f 0 k 0. To compute f n k , consider two cases: either add the nth item to our knapsack or don’t add it. Recurrence relation: f n k f n 1 k if wn k f n 1 k f n 1 k wn vn

  • therwise

Answer: f n W Time complexity: O nW What if we can use each item as many times as we want?

14

slide-40
SLIDE 40

Example 3 – Solution

DP state: f(n, k) = Maximum value of items that can be placed in the knapsack from items {1, 2, . . . , n} given capacity k. Base case: f(0, k) = 0. To compute f n k , consider two cases: either add the nth item to our knapsack or don’t add it. Recurrence relation: f n k f n 1 k if wn k f n 1 k f n 1 k wn vn

  • therwise

Answer: f n W Time complexity: O nW What if we can use each item as many times as we want?

14

slide-41
SLIDE 41

Example 3 – Solution

DP state: f(n, k) = Maximum value of items that can be placed in the knapsack from items {1, 2, . . . , n} given capacity k. Base case: f(0, k) = 0. To compute f(n, k), consider two cases: either add the nth item to our knapsack or don’t add it. Recurrence relation: f n k f n 1 k if wn k f n 1 k f n 1 k wn vn

  • therwise

Answer: f n W Time complexity: O nW What if we can use each item as many times as we want?

14

slide-42
SLIDE 42

Example 3 – Solution

DP state: f(n, k) = Maximum value of items that can be placed in the knapsack from items {1, 2, . . . , n} given capacity k. Base case: f(0, k) = 0. To compute f(n, k), consider two cases: either add the nth item to our knapsack or don’t add it. Recurrence relation: f(n, k) = { f(n − 1, k) if wn > k max ( f(n − 1, k), f(n − 1, k − wn) + vn )

  • therwise

Answer: f(n, W) Time complexity: O(nW) What if we can use each item as many times as we want?

14

slide-43
SLIDE 43

Problem 1 – Coins

Let’s play a game! n = 2k coins on the table with values v1, v2, . . . , vn. Player 1 and 2 alternate taking one coin from either leħt or right end. How much does each player get if each player plays optimally assuming that the other player also plays optimally?

15

slide-44
SLIDE 44

Problem 1 – Solution

DP state: f(l, r) = your maximum score when coins l . . . r remain and it is your turn, assuming both players play optimally Base cases: f i i vi, f i i 1 vi vi

1 .

Recursive case: consider picking either the lth coin or the rth coin and recursing on the possible choices that the opponent can make. Recurrence relation: f l r vl f l 2 r f l 1 r 1 vr f l 1 r 1 f l r 2 Answer: f 1 n . Time complexity: O n2

16

slide-45
SLIDE 45

Problem 1 – Solution

DP state: f(l, r) = your maximum score when coins l . . . r remain and it is your turn, assuming both players play optimally Base cases: f(i, i) = vi, f(i, i + 1) = max(vi, vi+1). Recursive case: consider picking either the lth coin or the rth coin and recursing on the possible choices that the opponent can make. Recurrence relation: f l r vl f l 2 r f l 1 r 1 vr f l 1 r 1 f l r 2 Answer: f 1 n . Time complexity: O n2

16

slide-46
SLIDE 46

Problem 1 – Solution

DP state: f(l, r) = your maximum score when coins l . . . r remain and it is your turn, assuming both players play optimally Base cases: f(i, i) = vi, f(i, i + 1) = max(vi, vi+1). Recursive case: consider picking either the lth coin or the rth coin and recursing on the possible choices that the opponent can make. Recurrence relation: f l r vl f l 2 r f l 1 r 1 vr f l 1 r 1 f l r 2 Answer: f 1 n . Time complexity: O n2

16

slide-47
SLIDE 47

Problem 1 – Solution

DP state: f(l, r) = your maximum score when coins l . . . r remain and it is your turn, assuming both players play optimally Base cases: f(i, i) = vi, f(i, i + 1) = max(vi, vi+1). Recursive case: consider picking either the lth coin or the rth coin and recursing on the possible choices that the opponent can make. Recurrence relation: f(l, r) = max { vl + min ( f(l + 2, r), f(l + 1, r − 1) ) vr + min ( f(l + 1, r − 1), f(l, r − 2) ) Answer: f(1, n). Time complexity: O(n2)

16

slide-48
SLIDE 48

Problem 2 – Box stacking

You are given a set of n 3-dimensional boxes. You can place box i on top of box j if the dimensions of the base of box i are strictly smaller than that of the base of box j. You can rotate the boxes and use multiple copies of the same box. What is the height of the tallest stack that can be made?

17

slide-49
SLIDE 49

Problem 2 – Solution

We can rotate box and use multiple copies of same box

  • Create 3 copies of each box (1 for each rotation)

Box i on top of box j only if both dimensions of the base are smaller.

  • Base area of box i

base area of box j

  • Sort boxes in descending order of base area

18

slide-50
SLIDE 50

Problem 2 – Solution

We can rotate box and use multiple copies of same box

  • Create 3 copies of each box (1 for each rotation)

Box i on top of box j only if both dimensions of the base are smaller.

  • Base area of box i

base area of box j

  • Sort boxes in descending order of base area

18

slide-51
SLIDE 51

Problem 2 – Solution

We can rotate box and use multiple copies of same box

  • Create 3 copies of each box (1 for each rotation)

Box i on top of box j only if both dimensions of the base are smaller.

  • Base area of box i < base area of box j
  • Sort boxes in descending order of base area

18

slide-52
SLIDE 52

Problem 2 – Solution

DP state: f(i) = Height of the tallest stack from boxes 1, 2, . . . , i with box i on top. Base case: f 1 height of box 1. To compute f i we consider adding box i onto the best possible stack from 1 2 i 1. Recurrence relation: f i height of box i

j f j where 1

j i, and we can put box i on box j Answer:

i f i for 1

i 3n Time complexity: O n2

19

slide-53
SLIDE 53

Problem 2 – Solution

DP state: f(i) = Height of the tallest stack from boxes 1, 2, . . . , i with box i on top. Base case: f(1) = height of box 1. To compute f i we consider adding box i onto the best possible stack from 1 2 i 1. Recurrence relation: f i height of box i

j f j where 1

j i, and we can put box i on box j Answer:

i f i for 1

i 3n Time complexity: O n2

19

slide-54
SLIDE 54

Problem 2 – Solution

DP state: f(i) = Height of the tallest stack from boxes 1, 2, . . . , i with box i on top. Base case: f(1) = height of box 1. To compute f(i) we consider adding box i onto the best possible stack from 1, 2, . . . , i − 1. Recurrence relation: f i height of box i

j f j where 1

j i, and we can put box i on box j Answer:

i f i for 1

i 3n Time complexity: O n2

19

slide-55
SLIDE 55

Problem 2 – Solution

DP state: f(i) = Height of the tallest stack from boxes 1, 2, . . . , i with box i on top. Base case: f(1) = height of box 1. To compute f(i) we consider adding box i onto the best possible stack from 1, 2, . . . , i − 1. Recurrence relation: f(i) = height of box i + maxj f(j) where 1 ≤ j < i, and we can put box i on box j Answer: maxi f(i) for 1 ≤ i ≤ 3n Time complexity: O(n2)

19

slide-56
SLIDE 56

Problem 3 – Palindromic path

You have m × n grid of integers with 1 ≤ m, n ≤ 100. You can only move down or right. Find the number of palindromic paths from (1, 1) to (m, n).

20

slide-57
SLIDE 57

Problem 3 – Solution

DP state: f(si, sj, ei, ej) = Number of palindromic paths that start at (si, sj) and end at (ei, ej). Base case: f si sj ei ej if cannot move from si sj to ei ej

  • r A si sj

A ei ej 1 if same/adjacent start/end and A si sj A ei ej To compute f si sj ei ej we sum over the answers to all possible ways of moving from the two endpoints. Recurrence relation (assuming A si sj A ei ej ): f si sj ei ej f si 1 sj ei 1 ej f si 1 sj ei ej 1 f si sj 1 ei 1 ej f si sj 1 ei ej 1 Time complexity: O m2n2

21

slide-58
SLIDE 58

Problem 3 – Solution

DP state: f(si, sj, ei, ej) = Number of palindromic paths that start at (si, sj) and end at (ei, ej). Base case: f(si, sj, ei, ej) = { if cannot move from (si, sj) to (ei, ej), or A[si][sj] ̸= A[ei][ej] 1 if same/adjacent start/end and A[si][sj] = A[ei][ej] To compute f si sj ei ej we sum over the answers to all possible ways of moving from the two endpoints. Recurrence relation (assuming A si sj A ei ej ): f si sj ei ej f si 1 sj ei 1 ej f si 1 sj ei ej 1 f si sj 1 ei 1 ej f si sj 1 ei ej 1 Time complexity: O m2n2

21

slide-59
SLIDE 59

Problem 3 – Solution

DP state: f(si, sj, ei, ej) = Number of palindromic paths that start at (si, sj) and end at (ei, ej). Base case: f(si, sj, ei, ej) = { if cannot move from (si, sj) to (ei, ej), or A[si][sj] ̸= A[ei][ej] 1 if same/adjacent start/end and A[si][sj] = A[ei][ej] To compute f(si, sj, ei, ej) we sum over the answers to all possible ways of moving from the two endpoints. Recurrence relation (assuming A si sj A ei ej ): f si sj ei ej f si 1 sj ei 1 ej f si 1 sj ei ej 1 f si sj 1 ei 1 ej f si sj 1 ei ej 1 Time complexity: O m2n2

21

slide-60
SLIDE 60

Problem 3 – Solution

DP state: f(si, sj, ei, ej) = Number of palindromic paths that start at (si, sj) and end at (ei, ej). Base case: f(si, sj, ei, ej) = { if cannot move from (si, sj) to (ei, ej), or A[si][sj] ̸= A[ei][ej] 1 if same/adjacent start/end and A[si][sj] = A[ei][ej] To compute f(si, sj, ei, ej) we sum over the answers to all possible ways of moving from the two endpoints. Recurrence relation (assuming A[si][sj] = A[ei][ej]): f(si, sj, ei, ej) = f(si + 1, sj, ei − 1, ej) + f(si + 1, sj, ei, ej − 1) + f(si, sj + 1, ei − 1, ej) + f(si, sj + 1, ei, ej − 1) Time complexity: O(m2n2)

21

slide-61
SLIDE 61

Example 4 – Longest common subsequence

Find the length of the largest common subsequence of two strings a and b of lengths m and n respectively.

a = XMJYAUZ b = MZJAWXZU LCS = MJAU.

22

slide-62
SLIDE 62

Example 4 – Solution

DP state: f(i, j) = length of the LCS of a[i . . . n] and b[j . . . m]. Base case: f i j 0 when i n or j m. To compute f n , either a i b j and we can consider the LCS of the 2 shorter strings, or a i b j and we can choose between making 1 of the strings shorter. Recurrence relation: f i j f i 1 j 1 1 if a i b j f i 1 j f i j 1

  • therwise

. Answer: f 1 1 . Time Complexity: O mn .

23

slide-63
SLIDE 63

Example 4 – Solution

DP state: f(i, j) = length of the LCS of a[i . . . n] and b[j . . . m]. Base case: f(i, j) = 0 when i > n or j > m. To compute f n , either a i b j and we can consider the LCS of the 2 shorter strings, or a i b j and we can choose between making 1 of the strings shorter. Recurrence relation: f i j f i 1 j 1 1 if a i b j f i 1 j f i j 1

  • therwise

. Answer: f 1 1 . Time Complexity: O mn .

23

slide-64
SLIDE 64

Example 4 – Solution

DP state: f(i, j) = length of the LCS of a[i . . . n] and b[j . . . m]. Base case: f(i, j) = 0 when i > n or j > m. To compute f(n), either a[i] = b[j] and we can consider the LCS of the 2 shorter strings, or a[i] ̸= b[j] and we can choose between making 1 of the strings shorter. Recurrence relation: f i j f i 1 j 1 1 if a i b j f i 1 j f i j 1

  • therwise

. Answer: f 1 1 . Time Complexity: O mn .

23

slide-65
SLIDE 65

Example 4 – Solution

DP state: f(i, j) = length of the LCS of a[i . . . n] and b[j . . . m]. Base case: f(i, j) = 0 when i > n or j > m. To compute f(n), either a[i] = b[j] and we can consider the LCS of the 2 shorter strings, or a[i] ̸= b[j] and we can choose between making 1 of the strings shorter. Recurrence relation: f(i, j) = { f(i + 1, j + 1) + 1 if a[i] = b[j] max{f(i + 1, j), f(i, j + 1)}

  • therwise

. Answer: f(1, 1). Time Complexity: O(mn).

23

slide-66
SLIDE 66

Problem 4 – Modified LCS

Find the LCS of two strings that does not contain the string “490” as a substring.

24

slide-67
SLIDE 67

Problem 4 – Solution

Idea: keep track of which character of “490” that matches DP state: f(i, j, k) = length of LCS of a[i . . . n] and b[j . . . m] that ends with the first k characters of “490” When we add one character, use k to figure out how many characters of “490” the suffjx will match! We’ll disallow matching the suffjx to all of “490” (since that means our LCS contains “490”).

25

slide-68
SLIDE 68

Problem 4 – Solution (continued)

Specifically, say we are at state k, which represents k = length of max prefix of “490” that matches suffjx of LCS and we see character c, then we can try appending c to the prefix of length k, and find out the new length k′ of the longest prefix that still matches the suffjx. In this case, we’re lucky, since “490” doesn’t have any self-similarity. If a character doesn’t match, we go back to k′ = 0, unless it’s a 4, in which case we get k′ = 1. (Extension: What if we have to match something like “49490”? This gives rise to the Knuth-Morris-Pratt algorithm for string matching.)

26

slide-69
SLIDE 69

Problem 4 – Solution (continued)

To organize our transitions, it’s helpful to draw a DFA:

27

slide-70
SLIDE 70

Problem 5 – Solution (continued)

Recurrence relation: f(i, j, 0) = max        f(i + 1, j, 0), f(i, j + 1, 0) f(i + 1, j + 1, 0) + 1 if a[i] = b[j] ̸= ‘4’ f(i + 1, j + 1, 1) + 1 if a[i] = b[j] = ‘4’ f(i, j, 1) = max        f(i + 1, j, 1), f(i, j + 1, 1) f(i + 1, j + 1, 1) + 1 if a[i] = b[j] = ‘4’ f(i + 1, j + 1, 2) + 1 if a[i] = b[j] = ‘9’ f(i, j, 2) = max        f(i + 1, j, 2), f(i, j + 1, 2) f(i + 1, j + 1, 0) + 1 if a[i] = b[j] ̸= ‘4’, ‘0’ f(i + 1, j + 1, 1) + 1 if a[i] = b[j] = ‘4’ Answer: max{f(1, 1, 0), f(1, 1, 1), f(1, 1, 2)} Time complexity: O(mn)

28

slide-71
SLIDE 71

Problem 5 – Rock-paper-scissors

Consider the game of rock-paper-scissors. There are:

  • r people who always play rock,
  • p people who always play paper.
  • s people who always play scissors,

In each round, 2 random people play each other, with all pairs being equally likely and the loser gets knocked out.

  • What is the probability that only rock players survive in the long run?
  • What about paper players?
  • What about scissor players?

29

slide-72
SLIDE 72

Problem 5 – Solution attempt

Let’s consider the probability of all the rock players surviving since the other 2 cases are similar. DP state: f(i, j, k) = probability of reaching a state with only rock players leħt, if there are i rock players, j paper players, and k scissors players leħt in the game. Base case: f i 0 0 1. To find the recurrence, we’ll look at the possibilities when playing one round.

30

slide-73
SLIDE 73

Problem 5 – Solution attempt

Let’s consider the probability of all the rock players surviving since the other 2 cases are similar. DP state: f(i, j, k) = probability of reaching a state with only rock players leħt, if there are i rock players, j paper players, and k scissors players leħt in the game. Base case: f(i, 0, 0) = 1. To find the recurrence, we’ll look at the possibilities when playing one round.

30

slide-74
SLIDE 74

Problem 5 – Solution attempt

Let’s consider the probability of all the rock players surviving since the other 2 cases are similar. DP state: f(i, j, k) = probability of reaching a state with only rock players leħt, if there are i rock players, j paper players, and k scissors players leħt in the game. Base case: f(i, 0, 0) = 1. To find the recurrence, we’ll look at the possibilities when playing one round.

30

slide-75
SLIDE 75

Problem 5 – Solution attempt

Recurrence relation: f(i, j, k) = (i

2

) + (j

2

) + (k

2

) (i+j+k

2

) · f(i, j, k) (a tie) + ij (i+j+k

2

) · f(i − 1, j, k) (rock plays paper) + jk (i+j+k

2

) · f(i, j − 1, k) (paper plays scissors) + ik (i+j+k

2

) · f(i, j, k − 1) (rock plays scissors) Answer: f(r, p, s). Problem: the DP is circular! We need f i j k to compute f i j k .

31

slide-76
SLIDE 76

Problem 5 – Solution attempt

Recurrence relation: f(i, j, k) = (i

2

) + (j

2

) + (k

2

) (i+j+k

2

) · f(i, j, k) (a tie) + ij (i+j+k

2

) · f(i − 1, j, k) (rock plays paper) + jk (i+j+k

2

) · f(i, j − 1, k) (paper plays scissors) + ik (i+j+k

2

) · f(i, j, k − 1) (rock plays scissors) Answer: f(r, p, s). Problem: the DP is circular! We need f(i, j, k) to compute f(i, j, k).

31

slide-77
SLIDE 77

Problem 5 – Solution

Do some arithmetic: f(i, j, k) = (i

2)+(j 2)+(k 2)

(i+j+k

2 )

· f(i, j, k) + . . . ⇒ ( 1 − (i

2)+(j 2)+(k 2)

(i+j+k

2 )

) f(i, j, k) = . . . ⇒ f(i, j, k) =

ij ij+jk+ki · f(i − 1, j, k)

+

jk ij+jk+ki · f(i, j − 1, k)

+

ki ij+jk+ki · f(i, j, k − 1)

Time complexity: O(rsp).

32