Based On Stanford CS161 Slides From Summer 2021 by Karey Shi
Based On Stanford CS161 Slides From Summer 2021 by Karey Shi
2
مقدمه ای بر برنامه نویسی پو یا
3
DYNAMIC PROGRAMMING
4
DYNAMIC PROGRAMMING
6
DYNAMIC PROGRAMMING
7
DYNAMIC PROGRAMMING
8
DYNAMIC PROGRAMMING
9
DYNAMIC PROGRAMMING
10
DYNAMIC PROGRAMMING
Two approaches for DP
(2 different ways to think about and/or implement DP algorithms)
11
DYNAMIC PROGRAMMING
Two approaches for DP
(2 different ways to think about and/or implement DP algorithms)
12
DYNAMIC PROGRAMMING
Two approaches for DP
(2 different ways to think about and/or implement DP algorithms)
13
DYNAMIC PROGRAMMING
Two approaches for DP
(2 different ways to think about and/or implement DP algorithms)
14
DYNAMIC PROGRAMMING
Two approaches for DP
(2 different ways to think about and/or implement DP algorithms)
15
DYNAMIC PROGRAMMING
Richard Bellman invented the term in the 1950’s. He was working for
the RAND corporation at the time, which was employed by the Air
Force, and government projects needed flashy non-mathematical
non-researchy names to get funded and approved.
16
DIVIDE & CONQUER vs DP
DIVIDE-AND-CONQUER DYNAMIC PROGRAMMING
19
RECIPE FOR APPLYING DP
20
RECIPE FOR APPLYING DP
21
RECIPE FOR APPLYING DP
22
RECIPE FOR APPLYING DP
23
ﺳﻮال؟
24
پیداکردن بزرگ ترین
زیر رشته مشترک
25
LONGEST COMMON SUBSEQUENCE
A sequence Z is a SUBSEQUENCE of X if Z can be obtained from X by deleting symbols
26
LONGEST COMMON SUBSEQUENCE
A sequence Z is a SUBSEQUENCE of X if Z can be obtained from X by deleting symbols
Computational
the diff unix
Bioinformatics! linguistics!
command!
31
STEP 1: OPTIMAL SUBSTRUCTURE
SUBPROBLEM: Find the length of LCS’s of prefixes to X and Y.
X A C G G A T
Y A C T A T
32
STEP 1: OPTIMAL SUBSTRUCTURE
SUBPROBLEM: Find the length of LCS’s of prefixes to X and Y.
X A C G G A T
Y A C T A T
Examples:
C[2,3] = 2 (LCS of X2 and Y3 is AC)
Notation: denote this prefix ACT by Y3 C[5,4] = 3 (LCS of X5 and Y4 is ACA)
33
STEP 1: OPTIMAL SUBSTRUCTURE
SUBPROBLEM: Find the length of LCS’s of prefixes to X and Y.
X A C G G A T
Y A C T A T
Examples:
C[2,3] = 2 (LCS of X2 and Y3 is AC)
Notation: denote this prefix ACT by Y3 C[5,4] = 3 (LCS of X5 and Y4 is ACA)
35
STEP 1: OPTIMAL SUBSTRUCTURE
Let C[i, j] = length_of_LCS(Xi, Yj)
Consider the ends of our prefixes, X[i] and Y[j]. We have two cases:
Xi A C G G A Xi A C G G T
Yj A C T A Yj A C T A
36
STEP 1: OPTIMAL SUBSTRUCTURE
Let C[i, j] = length_of_LCS(Xi, Yj)
Consider the ends of our prefixes, X[i] and Y[j]. We have two cases:
Xi A C G G A Xi A C G G T
Yj A C T A Yj A C T A
37
STEP 1: OPTIMAL SUBSTRUCTURE
Let C[i, j] = length_of_LCS(Xi, Yj)
Consider the ends of our prefixes, X[i] and Y[j]. We have two cases:
Xi A C G G A Xi A C G G T
Yj A C T A Yj A C T A
38
STEP 1: OPTIMAL SUBSTRUCTURE
Let C[i, j] = length_of_LCS(Xi, Yj)
Consider the ends of our prefixes, X[i] and Y[j]. We have two cases:
Xi A C G G A Xi A C G G T
Yj A C T A Yj A C T A
Then, C[i, j] = 1 + C[i–1, j–1] Then, C[i, j] = max{ C[i–1, j], C[i, j–1] }
because LCS(Xi, Yj) = LCS(Xi–1, Yj-1) followed by A . Give A a chance to “match”: LCS(Xi, Yj) = LCS(Xi–1, Y )
Give T a chance to “match”: LCS(Xi, Yj) = LCS(Xi, Yj–1)
39
ﺳﻮال؟
40
LCS: RECIPE FOR APPLYING DP
41
STEP 2: RECURSIVE FORMULATION
Our recursive formulation:
0 if i = 0 or j = 0
C[ i, j ] = C[i–1, j–1] + 1 if X[i] = Y[j] and i, j > 0
max{ C[i–1, j], C[i, j–1] } if X[i] ≠ Y[j] and i, j > 0
42
STEP 2: RECURSIVE FORMULATION
Our recursive formulation:
0 if i = 0 or j = 0
C[ i, j ] = C[i–1, j–1] + 1 if X[i] = Y[j] and i, j > 0
max{ C[i–1, j], C[i, j–1] } if X[i] ≠ Y[j] and i, j > 0
0 if i = 0 or j = 0
C[ i, j ] = C[i–1, j–1] + 1 if X[i] = Y[j] and i, j > 0
max{ C[i–1, j], C[i, j–1] } if X[i] ≠ Y[j] and i, j > 0
Yj A C T A Yj A C T A
44
STEP 2: RECURSIVE FORMULATION
Our recursive formulation:
0 if i = 0 or j = 0
C[ i, j ] = C[i–1, j–1] + 1 if X[i] = Y[j] and i, j > 0
max{ C[i–1, j], C[i, j–1] } if X[i] ≠ Y[j] and i, j > 0
Yj A C T A Yj A C T A Yj A C T A
45
ﺳﻮال؟
46
LCS: RECIPE FOR APPLYING DP
47
STEP 3: WRITE A DP ALGORITHM
We’ll store answers to our subproblems C[i, j] in a table (this is our cache)!
48
STEP 3: WRITE A DP ALGORITHM
0 if i = 0 or j = 0
C[ i, j ] = C[i–1, j–1] + 1 if X[i] = Y[j] and i, j > 0
max{ C[i–1, j], C[i, j–1] } if X[i] ≠ Y[j] and i, j > 0
49
STEP 3: WRITE A DP ALGORITHM
0 if i = 0 or j = 0
C[ i, j ] = C[i–1, j–1] + 1 if X[i] = Y[j] and i, j > 0
max{ C[i–1, j], C[i, j–1] } if X[i] ≠ Y[j] and i, j > 0
50
STEP 3: WRITE A DP ALGORITHM
0 if i = 0 or j = 0
C[ i, j ] = C[i–1, j–1] + 1 if X[i] = Y[j] and i, j > 0
max{ C[i–1, j], C[i, j–1] } if X[i] ≠ Y[j] and i, j > 0
else:
C[i,j] = max{ C[i,j–1], C[i–1,j] }
return C[m,n]
51
STEP 3: WRITE A DP ALGORITHM
0 if i = 0 or j = 0
C[ i, j ] = C[i–1, j–1] + 1 if X[i] = Y[j] and i, j > 0
max{ C[i–1, j], C[i, j–1] } if X[i] ≠ Y[j] and i, j > 0
else:
C[i,j] = max{ C[i,j–1], C[i–1,j] } Case 2
return C[m,n]
52
STEP 3: WRITE A DP ALGORITHM
0 if i = 0 or j = 0
C[ i, j ] = C[i–1, j–1] + 1 if X[i] = Y[j] and i, j > 0
max{ C[i–1, j], C[i, j–1] } if X[i] ≠ Y[j] and i, j > 0
else:
Final answer
C[i,j] = max{ C[i,j–1], C[i–1,j] } Case 2
return C[m,n]
53
STEP 3: WRITE A DP ALGORITHM
0 if i = 0 or j = 0
C[ i, j ] = C[i–1, j–1] + 1 if X[i] = Y[j] and i, j > 0
max{ C[i–1, j], C[i, j–1] } if X[i] ≠ Y[j] and i, j > 0
else:
Final answer
C[i,j] = max{ C[i,j–1], C[i–1,j] } Case 2
return C[m,n]
Runtime: O(mn)
? 54
STEP 3: WRITE A DP ALGORITHM
0 if i = 0 or j = 0
C[ i, j ] = C[i–1, j–1] + 1 if X[i] = Y[j] and i, j > 0
max{ C[i–1, j], C[i, j–1] } if X[i] ≠ Y[j] and i, j > 0
else:
Final answer
C[i,j] = max{ C[i,j–1], C[i–1,j] } Case 2
return C[m,n]
Constant amount of work to fill
Runtime: O(mn) out each of the mn entries in C 55
ﺳﻮال؟
56
EXAMPLE
Y
A C T G Initialize an (m+1) x (n+1) 0-indexed array C
C[i,0] = C[0,j] = 0 for all i=0,...,m and j=0,...,n
0 0 0 0 0
A 0
C 0 Fill in our base
X G 0 cases first
G 0
A 0
57
EXAMPLE
Y
for i = 1,...,m and j = 1,...,n:
A C T G if X[i] = Y[j]:
C[i,j] = C[i–1,j–1] + 1
else:
0 0 0 0 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
A 0 1
C 0
X[i] = Y[j]
X G 0 C[i,j] = C[i–1,j–1] + 1
G 0
A 0
58
EXAMPLE
Y
for i = 1,...,m and j = 1,...,n:
A C T G if X[i] = Y[j]:
C[i,j] = C[i–1,j–1] + 1
else:
0 0 0 0 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
A 0 1 1
C 0
X[i] ≠ Y[j]
X G 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
G 0
A 0
59
EXAMPLE
Y
for i = 1,...,m and j = 1,...,n:
A C T G if X[i] = Y[j]:
C[i,j] = C[i–1,j–1] + 1
else:
0 0 0 0 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
A 0 1 1 1
C 0
X[i] ≠ Y[j]
X G 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
G 0
A 0
60
EXAMPLE
Y
for i = 1,...,m and j = 1,...,n:
A C T G if X[i] = Y[j]:
C[i,j] = C[i–1,j–1] + 1
else:
0 0 0 0 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
A 0 1 1 1 1
C 0
X[i] ≠ Y[j]
X G 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
G 0
A 0
61
EXAMPLE
Y
for i = 1,...,m and j = 1,...,n:
A C T G if X[i] = Y[j]:
C[i,j] = C[i–1,j–1] + 1
else:
0 0 0 0 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
A 0 1 1 1 1
C 0 1
X[i] ≠ Y[j]
X G 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
G 0
A 0
62
EXAMPLE
Y
for i = 1,...,m and j = 1,...,n:
A C T G if X[i] = Y[j]:
C[i,j] = C[i–1,j–1] + 1
else:
0 0 0 0 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
A 0 1 1 1 1
C 0 1 2
X[i] = Y[j]
X G 0 C[i,j] = C[i–1,j–1] + 1
G 0
A 0
63
EXAMPLE
Y
for i = 1,...,m and j = 1,...,n:
A C T G if X[i] = Y[j]:
C[i,j] = C[i–1,j–1] + 1
else:
0 0 0 0 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
A 0 1 1 1 1
C 0 1 2 2
X[i] ≠ Y[j]
X G 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
G 0
A 0
64
EXAMPLE
Y
for i = 1,...,m and j = 1,...,n:
A C T G if X[i] = Y[j]:
C[i,j] = C[i–1,j–1] + 1
else:
0 0 0 0 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
A 0 1 1 1 1
C 0 1 2 2 2
X[i] ≠ Y[j]
X G 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
G 0
A 0
65
EXAMPLE
Y
for i = 1,...,m and j = 1,...,n:
A C T G if X[i] = Y[j]:
C[i,j] = C[i–1,j–1] + 1
else:
0 0 0 0 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
A 0 1 1 1 1
C 0 1 2 2 2
X[i] ≠ Y[j]
X G 0 1 C[i,j] = max{ C[i,j–1], C[i–1,j] }
G 0
A 0
66
EXAMPLE
Y
for i = 1,...,m and j = 1,...,n:
A C T G if X[i] = Y[j]:
C[i,j] = C[i–1,j–1] + 1
else:
0 0 0 0 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
A 0 1 1 1 1
C 0 1 2 2 2
X[i] ≠ Y[j]
X G 0 1 2 C[i,j] = max{ C[i,j–1], C[i–1,j] }
G 0
A 0
67
EXAMPLE
Y
for i = 1,...,m and j = 1,...,n:
A C T G if X[i] = Y[j]:
C[i,j] = C[i–1,j–1] + 1
else:
0 0 0 0 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
A 0 1 1 1 1
C 0 1 2 2 2
X[i] ≠ Y[j]
X G 0 1 2 2 C[i,j] = max{ C[i,j–1], C[i–1,j] }
G 0
A 0
68
EXAMPLE
Y
for i = 1,...,m and j = 1,...,n:
A C T G if X[i] = Y[j]:
C[i,j] = C[i–1,j–1] + 1
else:
0 0 0 0 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
A 0 1 1 1 1
C 0 1 2 2 2
X[i] = Y[j]
X G 0 1 2 2 3 C[i,j] = C[i–1,j–1] + 1
G 0
A 0
69
EXAMPLE
Y
for i = 1,...,m and j = 1,...,n:
A C T G if X[i] = Y[j]:
C[i,j] = C[i–1,j–1] + 1
else:
0 0 0 0 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
A 0 1 1 1 1
C 0 1 2 2 2
X[i] ≠ Y[j]
X G 0 1 2 2 3 C[i,j] = max{ C[i,j–1], C[i–1,j] }
G 0 1
A 0
70
EXAMPLE
Y
for i = 1,...,m and j = 1,...,n:
A C T G if X[i] = Y[j]:
C[i,j] = C[i–1,j–1] + 1
else:
0 0 0 0 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
A 0 1 1 1 1
C 0 1 2 2 2
X[i] ≠ Y[j]
X G 0 1 2 2 3 C[i,j] = max{ C[i,j–1], C[i–1,j] }
G 0 1 2
A 0
71
EXAMPLE
Y
for i = 1,...,m and j = 1,...,n:
A C T G if X[i] = Y[j]:
C[i,j] = C[i–1,j–1] + 1
else:
0 0 0 0 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
A 0 1 1 1 1
C 0 1 2 2 2
X[i] ≠ Y[j]
X G 0 1 2 2 3 C[i,j] = max{ C[i,j–1], C[i–1,j] }
G 0 1 2 2
A 0
72
EXAMPLE
Y
for i = 1,...,m and j = 1,...,n:
A C T G if X[i] = Y[j]:
C[i,j] = C[i–1,j–1] + 1
else:
0 0 0 0 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
A 0 1 1 1 1
C 0 1 2 2 2
X[i] = Y[j]
X G 0 1 2 2 3 C[i,j] = C[i–1,j–1] + 1
G 0 1 2 2 3
A 0
73
EXAMPLE
Y
for i = 1,...,m and j = 1,...,n:
A C T G if X[i] = Y[j]:
C[i,j] = C[i–1,j–1] + 1
else:
0 0 0 0 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
A 0 1 1 1 1
C 0 1 2 2 2
X[i] = Y[j]
X G 0 1 2 2 3 C[i,j] = C[i–1,j–1] + 1
G 0 1 2 2 3
A 0 1
74
EXAMPLE
Y
for i = 1,...,m and j = 1,...,n:
A C T G if X[i] = Y[j]:
C[i,j] = C[i–1,j–1] + 1
else:
0 0 0 0 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
A 0 1 1 1 1
C 0 1 2 2 2
X[i] ≠ Y[j]
X G 0 1 2 2 3 C[i,j] = max{ C[i,j–1], C[i–1,j] }
G 0 1 2 2 3
A 0 1 2
75
EXAMPLE
Y
for i = 1,...,m and j = 1,...,n:
A C T G if X[i] = Y[j]:
C[i,j] = C[i–1,j–1] + 1
else:
0 0 0 0 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
A 0 1 1 1 1
C 0 1 2 2 2
X[i] ≠ Y[j]
X G 0 1 2 2 3 C[i,j] = max{ C[i,j–1], C[i–1,j] }
G 0 1 2 2 3
A 0 1 2 2
76
EXAMPLE
Y
for i = 1,...,m and j = 1,...,n:
A C T G if X[i] = Y[j]:
C[i,j] = C[i–1,j–1] + 1
else:
0 0 0 0 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
A 0 1 1 1 1
C 0 1 2 2 2
X[i] ≠ Y[j]
X G 0 1 2 2 3 C[i,j] = max{ C[i,j–1], C[i–1,j] }
G 0 1 2 2 3
A 0 1 2 2 3
77
EXAMPLE
Y
for i = 1,...,m and j = 1,...,n:
A C T G if X[i] = Y[j]:
C[i,j] = C[i–1,j–1] + 1
else:
0 0 0 0 0 C[i,j] = max{ C[i,j–1], C[i–1,j] }
A 0 1 1 1 1
C 0 1 2 2 2
So the LCM of X and Y
X G 0 1 2 2 3
has length 3.
G 0 1 2 2 3
A 0 1 2 2 3
78
ﺳﻮال؟
79
LCS: RECIPE FOR APPLYING DP
80
STEP 4: FIND ACTUAL LCS
Y
A C T G Suppose we want to
recover the actual LCS.
0 0 0 0 0 How can we construct the actual LCS
A 0 1 1 1 1 given this table C that we just filled out?
C 0 1 2 2 2
X G 0 1 2 2 3
G 0 1 2 2 3
A 0 1 2 2 3
81
STEP 4: FIND ACTUAL LCS
Y
A C T G Suppose we want to
recover the actual LCS.
0 0 0 0 0 How can we construct the actual LCS
A 0 1 1 1 1 given this table C that we just filled out?
0 0 0 0 0
A 0 1 1 1 1
C 0 1 2 2 2
X G 0 1 2 2 3
G 0 1 2 2 3 LCS of X and Y:
A 0 1 2 2 3
87
STEP 4: FIND ACTUAL LCS
Y
A C T G
X[5] ≠ Y[4]
0 0 0 0 0 We don’t add anything to our LCS.
A 0 1 1 1 1 But we can go up → C[4,4]
C 0 1 2 2 2
X G 0 1 2 2 3
G 0 1 2 2 3 LCS of X and Y:
A 0 1 2 2 3
88
STEP 4: FIND ACTUAL LCS
Y
A C T G
X[4] = Y[4]
0 0 0 0 0 We can add “G” to our LCS
A 0 1 1 1 1 We go diagonally back → C[3,3]
C 0 1 2 2 2
X G 0 1 2 2 3
G 0 1 2 2 3 LCS of X and Y: G
A 0 1 2 2 3
89
STEP 4: FIND ACTUAL LCS
Y
A C T G
X[3] ≠ Y[3]
0 0 0 0 0 We don’t add anything to our LCS.
A 0 1 1 1 1 But we can go up → C[2,3]
(Going left is okay too since it’s a tie. How you choose to break ties might
C 0 1 2 2 2 result in different LCS’s when there are multiple. In this example, there’s
actually only one LCS so we we’ll end up with the same LCS either way)
X G 0 1 2 2 3
G 0 1 2 2 3 LCS of X and Y: G
A 0 1 2 2 3
90
STEP 4: FIND ACTUAL LCS
Y
A C T G
X[2] ≠ Y[3]
0 0 0 0 0 We don’t add anything to our LCS.
A 0 1 1 1 1 But we can go left → C[2,2]
C 0 1 2 2 2
X G 0 1 2 2 3
G 0 1 2 2 3 LCS of X and Y: G
A 0 1 2 2 3
91
STEP 4: FIND ACTUAL LCS
Y
A C T G
X[2] = Y[2]
0 0 0 0 0 We can add “C” to our LCS.
A 0 1 1 1 1 We go diagonally back → C[1,1]
C 0 1 2 2 2
X G 0 1 2 2 3
G 0 1 2 2 3 LCS of X and Y: C G
A 0 1 2 2 3
92
STEP 4: FIND ACTUAL LCS
Y
A C T G
X[1] = Y[1]
0 0 0 0 0 We can add “A” to our LCS.
A 0 1 1 1 1 We’re done!
C 0 1 2 2 2
X G 0 1 2 2 3
G 0 1 2 2 3 LCS of X and Y: A C G
A 0 1 2 2 3
93
ﺳﻮال؟
94
LCS: RECIPE FOR APPLYING DP
1. Identify optimal substructure. What are your overlapping subproblems?
2. Define a recursive formulation. Recursively define your optimal solution in terms
of sub-solutions. Always write down this formulation.
3. Use dynamic programming. Turn the recursive formulation into a DP algorithm.
4. If needed, track additional information. You may need to solve a related
problem, e.g. step 3 finds you an optimal value/cost, but you need to recover the
actual optimal solution/path/subset/substring/etc. Go back and modify your
algorithm in step 3 to make this happen.
5. Can we do better? Any wasted space? Other things to optimize?
(We won’t focus on this step too much in lecture/assignments/exams, but in practice, this is definitely a very important step to always consider)!
95
STEP 5: CAN WE DO BETTER?
● If we only care about the length of the LCS, then we don’t need to store the entire
table (we can just store 2 rows at a time).
● If we want to recover the entire LCS, we do need to keep the whole table.
● Can we improve the runtime of O(mn)?
○ If you have a bounded alphabet size, you can reduce the running time of the DP algorithm
by a logarithmic factor (using the Method of Four Russians).
○ The general LCS problem is NP-hard, so performing much better is an open problem!
96
STEP 5: CAN WE DO BETTER?
● If we only care about the length of the LCS, then we don’t need to store the entire
table (we can just store 2 rows at a time).
● If we want to recover the entire LCS, we do need to keep the whole table.
● Can we improve the runtime of O(mn)?
○ If you have a bounded alphabet size, you can reduce the running time of the DP algorithm
by a logarithmic factor (using the Method of Four Russians).
○ The general LCS problem is NP-hard, so performing much better is an open problem!
97
STEP 5: CAN WE DO BETTER?
● If we only care about the length of the LCS, then we don’t need to store the entire
table (we can just store 2 rows at a time).
● If we want to recover the entire LCS, we do need to keep the whole table.
● Can we improve the runtime of O(mn)?
○ If you have a bounded alphabet size, you can reduce the running time of the DP algorithm
by a logarithmic factor (using the Method of Four Russians).
○ The general LCS problem is NP-hard, so performing much better is an open problem!
98
STEP 5: CAN WE DO BETTER?
● If we only care about the length of the LCS, then we don’t need to store the entire
table (we can just store 2 rows at a time).
● If we want to recover the entire LCS, we do need to keep the whole table.
● Can we improve the runtime of O(mn)?
○ If you have a bounded alphabet size, you can reduce the running time of the DP algorithm
by a logarithmic factor (using the Method of Four Russians).
○ The general LCS problem is NP-hard, so performing much better is an open problem!
99
STEP 5: CAN WE DO BETTER?
● If we only care about the length of the LCS, then we don’t need to store the entire
table (we can just store 2 rows at a time).
● If we want to recover the entire LCS, we do need to keep the whole table.
● Can we improve the runtime of O(mn)?
○ If you have a bounded alphabet size, you can reduce the running time of the DP algorithm
by a logarithmic factor (using the Method of Four Russians).
○ The general LCS problem is NP-hard, so performing much better is an open problem!
100
STEP 5: CAN WE DO BETTER?
● If we only care about the length of the LCS, then we don’t need to store the entire
table (we can just store 2 rows at a time).
● If we want to recover the entire LCS, we do need to keep the whole table.
● Can we improve the runtime of O(mn)?
○ If you have a bounded alphabet size, you can reduce the running time of the DP algorithm
by a logarithmic factor (using the Method of Four Russians).
○ The general LCS problem is NP-hard, so performing much better is an open problem!
101
ﺳﻮال؟
102