Dynamic Programming Code Straightforward top-down rod cutting • CUT-ROD(p, n) – If n == 0 • Return 0 – q = -1 – For I = 1 to n • q = max (q, p[i] + CUT-ROD(p, n-i)) – Return q Memoization in rod cutting • MEMOIZED-CUT-ROD(p, n) – let r[0..n] be a new array – for I = 0 to n • r[i] = -1 – return MEMOIZED-CUT-ROD-AUX(p, n, r) • MEMOIZED-CUT-ROD-AUX (p, n, r) – if r[n] >= 0 • return r[n] – if n == 0 • q=0 – else • q = -1 • For I = 1 to n – q = max (q, p[i] + MEMOIZED-CUT-ROD-AUX(p, n-i, r)) – r[n] = q – return q Bottom up memoization • BOTTOM-UP-CUT-ROD(p, n) – let r[0..n] be a new array – r[0] = 0 – for j = 1 to n • q = -1 • for i = 1 to j – q = max (q, p[i] + r[j – i]) • r[j] = q – return r[n] – How do we know where to make the cuts? Bottom up memoization • EXTENDED-BOTTOM-UP-CUT-ROD(p, n) – let r[0..n] and s[0..n] be a new array – r[0] = 0 – for j = 1 to n • How do you print the solution? • q = -1 • for i = 1 to j – if q < p[i] + r[j – 1] » q = p[i] + r[j – 1] » s[j] = i • r[j] = q – return r[n] Bottom up memoization • EXTENDED-BOTTOM-UP-CUT-ROD(p, n) – let r[0..n] and s[0..n] be a new array – r[0] = 0 – for j = 1 to n • PRINT-CUT-ROD-SOLUTION(p, n) • q = -1 • (r, s) = EXT-BUCR(p, n) • for i = 1 to j • while n > 0 – if q < p[i] + r[j – 1] • print s[n] » q = p[i] + r[j – 1] • n = n – s[n] » s[j] = i • r[j] = q – return r[n] LCS Theorem Let Z = z1, . . . , zk be any LCS of X and Y . 1. If xm = yn, then zk = xm = yn and Zk-1 is an LCS of Xm-1 and Yn-1. 2. If xm yn, then either zk xm and Z is an LCS of Xm-1 and Y . 3. or zk yn and Z is an LCS of X and Yn-1. LCS-LENGTH (X, Y) 1. m ← length[X] 2. n ← length[Y] 3. for i ← 1 to m 4. do c[i, 0] ← 0 5. for j ← 0 to n 6. do c[0, j ] ← 0 7. for i ← 1 to m 8. do for j ← 1 to n 9. do if xi = yj 10. then c[i, j ] ← c[i1, j1] + 1 11. 12. else if c[i1, j ] ≥ c[i, j1] 13. then c[i, j ] ← c[i 1, j ] 14. 15. else c[i, j ] ← c[i, j1] 16. 17. return c LCS-LENGTH (X, Y) 1. m ← length[X] 2. n ← length[Y] 3. for i ← 1 to m 4. do c[i, 0] ← 0 5. for j ← 0 to n 6. do c[0, j ] ← 0 7. for i ← 1 to m 8. do for j ← 1 to n 9. do if xi = yj 10. then c[i, j ] ← c[i1, j1] + 1 11. b[i, j ] ← “ ” 12. else if c[i1, j ] ≥ c[i, j1] 13. then c[i, j ] ← c[i 1, j ] 14. b[i, j ] ← “↑” 15. else c[i, j ] ← c[i, j1] 16. b[i, j ] ← “←” 17. return c and b PRINT-LCS (b, X, i, j) 1. if i = 0 or j = 0 2. then return 3. if b[i, j ] = “ ” 4. then PRINT-LCS(b, X, i1, j1) 5. print xi 6. elseif b[i, j ] = “↑” 7. then PRINT-LCS(b, X, i1, j) 8. else PRINT-LCS(b, X, i, j1) Matrix-chain Multiplication coitweb.uncc.edu/~ras/courses/Matrix-Mult.ppt • Suppose we have a sequence or chain A1, A2, …, An of n matrices to be multiplied – That is, we want to compute the product A1A2…An • There are many possible ways (parenthesizations) to compute the product 11-11 Matrix-chain Multiplication • …contd Example: consider the chain A1, A2, A3, A4 of 4 matrices – Let us compute the product A1A2A3A4 • There are 5 possible ways: 1. 2. 3. 4. 5. (A1(A2(A3A4))) (A1((A2A3)A4)) ((A1A2)(A3A4)) ((A1(A2A3))A4) (((A1A2)A3)A4) 11-12 Matrix-chain Multiplication • …contd To compute the number of scalar multiplications necessary, we must know: – Algorithm to multiply two matrices – Matrix dimensions • Can you write the algorithm to multiply two matrices? 11-13 Algorithm to Multiply 2 Matrices Input: Matrices Ap×q and Bq×r (with dimensions p×q and q×r) Result: Matrix Cp×r resulting from the product A·B MATRIX-MULTIPLY(Ap×q , Bq×r) 1. for i ← 1 to p 2. for j ← 1 to r 3. C[i, j] ← 0 4. for k ← 1 to q 5. C[i, j] ← C[i, j] + A[i, k] · B[k, j] 6. return C Scalar multiplication in line 5 dominates time to compute CNumber of scalar multiplications = pqr 11-14 Matrix-chain Multiplication • • …contd Example: Consider three matrices A10100, B1005, and C550 There are 2 ways to parenthesize – ((AB)C) = D105 · C550 • • AB 10·100·5=5,000 scalar multiplications DC 10·5·50 =2,500 scalar multiplications Total: 7,500 – (A(BC)) = A10100 · E10050 • • BC 100·5·50=25,000 scalar multiplications AE 10·100·50 =50,000 scalar multiplications Total: 75,000 11-15 Matrix-chain Multiplication • …contd Matrix-chain multiplication problem – Given a chain A1, A2, …, An of n matrices, where for i=1, 2, …, n, matrix Ai has dimension pi-1pi – Parenthesize the product A1A2…An such that the total number of scalar multiplications is minimized • Brute force method of exhaustive search takes time exponential in n 11-16 Dynamic Programming Approach • The structure of an optimal solution – Let us use the notation Ai..j for the matrix that results from the product Ai Ai+1 … Aj – An optimal parenthesization of the product A1A2…An splits the product between Ak and Ak+1 for some integer k where1 ≤ k < n – First compute matrices A1..k and Ak+1..n ; then multiply them to get the final matrix A1..n 11-17 Dynamic Programming Approach …contd – Key observation: parenthesizations of the subchains A1A2…Ak and Ak+1Ak+2…An must also be optimal if the parenthesization of the chain A1A2…An is optimal (why?) – That is, the optimal solution to the problem contains within it the optimal solution to subproblems 11-18 Dynamic Programming Approach …contd • Recursive definition of the value of an optimal solution – Let m[i, j] be the minimum number of scalar multiplications necessary to compute Ai..j – Minimum cost to compute A1..n is m[1, n] – Suppose the optimal parenthesization of Ai..j splits the product between Ak and Ak+1 for some integer k where i ≤ k < j 11-19 Dynamic Programming Approach …contd – Ai..j = (Ai Ai+1…Ak)·(Ak+1Ak+2…Aj)= Ai..k · Ak+1..j – Cost of computing Ai..j = cost of computing Ai..k + cost of computing Ak+1..j + cost of multiplying Ai..k and Ak+1..j – Cost of multiplying Ai..k and Ak+1..j is pi-1pk pj – m[i, j ] = m[i, k] + m[k+1, j ] + pi-1pk pj k<j – m[i, i ] = 0 for i=1,2,…,n for i ≤ 11-20 Dynamic Programming Approach …contd – But… optimal parenthesization occurs at one value of k among all possible i ≤ k < j – Check all these and select the best one 0 m[i, j ] = min {m[i, k] + m[k+1, j ] + pi-1pk pj } if i=j if i<j i ≤ k< j 11-21 Dynamic Programming Approach …contd • • • To keep track of how to construct an optimal solution, we use a table s s[i, j ] = value of k at which Ai Ai+1 … Aj is split for optimal parenthesization Algorithm: next slide – First computes costs for chains of length l=1 – Then for chains of length l=2,3, … and so on – Computes the optimal cost bottom-up 11-22 Algorithm to Compute Optimal Cost Input: Array p[0…n] containing matrix dimensions and n Result: Minimum-cost table m and split table s MATRIX-CHAIN-ORDER(p[ ], n) for i ← 1 to n Takes O(n3) time m[i, i] ← 0 2) space Requires O(n for l ← 2 to n for i ← 1 to n-l+1 j ← i+l-1 m[i, j] ← for k ← i to j-1 q ← m[i, k] + m[k+1, j] + p[i-1] p[k] p[j] if q < m[i, j] m[i, j] ← q s[i, j] ← k return m and s 11-23 Constructing Optimal Solution • • Our algorithm computes the minimum-cost table m and the split table s The optimal solution can be constructed from the split table s – Each entry s[i, j ]=k shows where to split the product Ai Ai+1 … Aj for the minimum cost 11-24 Example • • Show how to multiply this matrix chain optimally Solution on the board – – Minimum cost 15,125 Optimal parenthesization ((A1(A2A3))((A4 A5)A6)) Matrix Dimension A1 30×35 A2 35×15 A3 15×5 A4 5×10 A5 10×20 A6 20×25 11-25 LPS (problem set 4) • A palindrome is a nonempty string over some alphabet that reads the same forward and backward. Examples of palilndromes are all strings of length 1, "civic", "racecar", and "aibohphobia" (fear of palindromes). • Give an efficient algorithm to find the longest palindrome that is a subsequence of a given input string. For example, given the input "character", your algorithm should return "carac". What is the running time of your algorithm?