Dynamic Programming Flashcards
LongestIncreasingSubsequence (Length)
Input: S = {x1,x2,…xn}
Output: L, the length of the LIS of S
Constraints: L(i) includes xi
LIS: L := 0 for each xi in S: m := 1 for each j in [1,i): if xi > xj and L(j) >= m then m = L(j) end if end for L(i) = m + 1 end for return max(L) end
Running time: O(n^2), Space: O(n)
LongestCommonSubsequence (Length)
Input: X = {x1, x2, .., xn}, a series of letters/numbers
Input: Y = {y1, y2, .., ym}, another series of letters/numbers
Output: L, length of the longest common subsequence of X and Y.
LCS: L(n,m) = {0} //empty list for i from 1 to n: for j from 1 to m: 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)] end if end for end for return L(n,m) end
Running time: O(n^2)
Properties/When to use Longest Increasing Subsequence?
- problem has only a single array
- problem comparing to itself
- problem looks back 1 element at a time
Properties/When to use Longest Common Subsequence?
- problem comparing between two arrays
- problem is looking for something in common
- normally a 2D table
Properties/When to use Knapsack?
- follow a formulation where selection is the optimal objects from a list that fits some criteria.
- values have a weight associated with them.
Knapsack (no repetition)
Input: W = {w1, w2, …, wn} List of object weights
Input: V = {v1, v2, …, vn} List of object values
Input: B, the capacity
Output: K, collection of objects resulting in max total value without exceeding B.
Knapsack: K(n+1, B+1) = 0 for i from 1 to n: for b from 1 to B: x=K(i-1,b) if wi <= b: K(i,b) = max[ x, vi+K(i-1, b-wi)] else: k(i,b) = x end if end for end for return K(n,B) end
Running time: O(nB)
Knapsack (with repetition)
Input: W = {w1, w2, …, wn} List of object weights
Input: V = {v1, v2, …, vn} List of object values
Input: B, the capacity
Output: K, collection of objects (possibly with duplicates) resulting in max total value without exceeding B.
Knapsack: K = 0 for b from 1 to B: K(b) = 0 for w in W: if wi <= b: K(b) = max[ K(b), vi+K(b-wi)] end for end for return K(B) end
Running time: O(nB)
Chain Matrix Multiply
Input: [m1 ,m2, … mn] Set of sizes corresponding to matrix dimensions
Output: Lowest-cost matrix multiplication possible
Chain Multiply: M(n,m) = null for i in 1 to n: M(i, i) = 0 end for
for d in 1 to (n-1): for i in 1 to (n-d): j = i + d M(i,j) = inf for k in i to (j-1): current = M(i, k) + M(k+1, j) + m(i-1)*mk*mj if current < M(i,j) M(i,j) = current end if end for end for end for return M(1,n) end
Running time: O(n^3)
Steps to solve a Dynamic Programming Problem
- Define the Input and Output.
- Define entries in table, i.e. T(i) or T(i, j) is…
- Define a Recurrence relationship - Based on a subproblem to the main problem. (hint: use a prefix of the original input 1 < i < n).
- Define the Pseudocode.
- Define the Runtime of the algorithm. Use Time Function notation here => T(n) = T(n/2) + 1…
In Bellman-Ford, how would you detect a negative weight cycle?
Check if iteration i (since bellman-ford does i -1 iteration) decreases a previous row result.
In Floyd-Warshall, how would you detect a negative weight cycle?
Check if the diagonal values have any negative values. This is because if we the length to and from the same node should be 0, not negative!
The main difference between Bellman-Ford and Floyd-Warshall?
Run time difference (mN^2 vs n^3) and Bellman-Ford computes the shortest path between two nodes, where Floyd-warshall does them all.
what takes more time, longest increasing subsequence or longest common subsequence?
longest increasing subsequence
LIS Variations: O(n) lookback
- need to check all previous elements
- need to check all previous elements < or > some requirement
- Results in O(n^2)
LIST variations: O(1) lookback
- need to check 1 element back.
- need to check constant # elements back.
- restriction moves forward with 1
- if you need to care the max, sum, count, etc. forward (this means you only compare with i-1)
- Results in O(n)