Dynamic Programming
::
2025-01-12Using the Dynamic Programming approach to solve Fibonacci, LIS, and LCS problems
Summary
How can we store previous subproblems and use that to quickly solve larger problems? This is particularly useful when naive solutions include recomputing some problems. This technique typically involves defining the subproblem in words, then defining a recurrenc relation.
Contents
- Fibonacci Numbers
- Steps to Solve DP problems
- Largest Increasing Subsequence (LIS)
- Longest Common Subsequence (LCS)
Fibonacci Numbers
Recursive Algorithm
Fib1(n):
if n == 0:
return 0
if n == 1:
return 1
return Fib1(n-1) + Fib1(n-2)
Runtime:
Runtime scales with the Fib numbers () which is exponential.
This is becase we are computing some solutions multiple times:
Dynamic Algorithm
Fib2(n):
F[0] = 0
F[1] = 1
for i in range(2,n):
F[i] = F[i-1] + F[i-2]
return F[n]
Runtime is O(n)
Steps to Solve DP problems
- Define subproblem in words
- F[i] = ith Fibonacci number
- State a recursive relation
- express F[i] in terms of F[1],…,F[i-1]
- F[i] = F[i-1] + F[i-2]
If the definition is not possible, you can strengthen it and prove the stronger version.
Largest Increasing Subsequence (LIS)
Input
:
Goal
: find length of LIS
substring
Set of consecutive elements
subsequence
Subset of elements in order (can skip)
Longest Increasing Subsequences is:
DP Solution
Let
LIS(A):
for i in range(0,n):
L[i] = 1
for j in range(0,i):
if A[j] < A[i] & L[i] < 1 + L[j]:
L[i] = L[j] + 1
max = 0
for i in range(1,n):
if L[i] > L[max]:
max = i
return L[max]
Running time is
Longest Common Subsequence (LCS)
Input
: 2 Strings
Goal
: Find the length of the longest string which is a subsequence of both X
and Y
Attempt 1
When
When , we can’t know what previous sequence it was matched on becuase X and Y have different lengths.
We need to store two parameters, one for the length in X, and another for Y
Attempt 2
Recurrence
Or more simply, for
LCS(X,Y):
for i in range(0,n):
L[i][0] = 0
for j in range(0,n):
L[0][j] = 0
for i in range(1,n):
for j in range(1,n):
if X[i] == Y[j]:
L[i][j] = 1 + L[i-1][j-1]
else:
L[i][j] = max(L[i][j-1], L[i-1][j])
return L[n][n]