Aaron Bloomfield (aaron@virginia.edu)
Raymond Pettit (raymond.pettit@virginia.edu)
@github | ↑ |
Readings in CLRS 4th edition: chapter 14
\(2 \times n\) board with dominoes?
How many ways to tile this: With these?
|
For example:
|
How many ways are there to tile a \(2 \times n\) board with dominoes?
Two ways to fill the final column:
\(n-1\)
\(n-2\)
\[Tile(0) = 1\] \[Tile(1) = 1\] \[Tile(n) = Tile(n-1) + Tile(n-2)\]
Tile(n):
if n < 2:
return 1
return Tile(n-1) + Tile(n-2)
Many redundant calls! |
Run time: \(\Theta(1.6^n)\) |
Better way: Use Memory! |
Initialize memory M
Tile(n):
if n < 2:
return 1
if M[n] is filled:
return M[n]
M[n] = Tile(n-1)+Tile(n-2)
return M[n]
Technique: memoization (note no ‘r’) |
M | |
0 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 |
Initialize memory M
Tile(n):
if n < 2:
return 1
if M[n] is filled:
return M[n]
M[n] = Tile(n-1)+Tile(n-2)
return M[n]
M | |
1 | 0 |
1 | 1 |
2 | 2 |
3 | 3 |
5 | 4 |
8 | 5 |
13 | 6 |
\(n-1\) |
\(n-2\) |
Initialize memory M
Tile(n):
if n < 2:
return 1
if M[n] is filled:
return M[n]
M[n] = Tile(n-1)+Tile(n-2)
return M[n]
Recursive calls happen in a predictable order
M | |
1 | 0 |
1 | 1 |
2 | 2 |
3 | 3 |
5 | 4 |
8 | 5 |
13 | 6 |
Tile(n):
Initialize memory M
M[0] = 1
M[1] = 1
for i = 2 to n:
M[i] = M[i-1] + M[i-2]
return M[n]
M | |
0 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 |
Readings in CLRS 4th edition: chapter 14, specifically 14.1
Find the best way to cut the log, given a log of length \(n\) and
a list (of length \(n\)) of prices \(P\) where \(P[i]\) is the price of a cut of size \(i\)
Price: | 1 | 5 | 8 | 9 | 10 | 17 | 17 | 20 | 24 | 30 |
Length: | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Brute force: \(O(2^n)\)
Greedy algorithms build a solution by picking the best option “right now”
|
|
Greedy: Lengths: 5, 1 Profit: 51 Better: Lengths: 2, 4 Profit: 54 |
Greedy algorithms build a solution by picking the best option “right now”
|
|
Greedy: Lengths: 5, 1 Profit: 51 Better: Lengths: 2, 4 Profit: 54 |
\(P[i] =\) value of a cut of length \(i\)
\(Cut(n)=\) value of best way to cut a log of length \(n\)
\[{\color{magenta}Cut(n)} = \max \begin{cases} {\color{magenta}Cut(n-1)} + \color{blue}{P[1]} \\ {\color{magenta}Cut(n-2)} + \color{blue}{P[2]} \\ \color{black}{\ldots} \\ {\color{magenta}Cut(0)} + \color{blue}{P[n]} \end{cases}\]
\(Cut(n-\ell_k)\) |
\(\ell_k\) |
|
Solve Smallest subproblem first
\[{\color{magenta}Cut(0)}=0\] |
Cut(i): | 0 | ||||||||||
Length: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Solve Smallest subproblem first
\[{\color{magenta}Cut(1)}={\color{magenta}Cut(0)}+\color{blue}{P[1]}\] |
Cut(i): | 0 | ||||||||||
Length: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Solve Smallest subproblem first
\[{\color{magenta}Cut(2)} = \max \begin{cases} {\color{magenta}Cut(1)} + \color{blue}{P[1]} \\ {\color{magenta}Cut(0)} + \color{blue}{P[2]} \\ \end{cases}\] |
Cut(i): | 0 | ||||||||||
Length: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Solve Smallest subproblem first
\[{\color{magenta}Cut(3)} = \max \begin{cases} {\color{magenta}Cut(2)} + \color{blue}{P[1]} \\ {\color{magenta}Cut(1)} + \color{blue}{P[2]} \\ {\color{magenta}Cut(0)} + \color{blue}{P[3]} \\ \end{cases}\] |
Cut(i): | 0 | ||||||||||
Length: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Solve Smallest subproblem first
\[{\color{magenta}Cut(4)} = \max \begin{cases} {\color{magenta}Cut(3)} + \color{blue}{P[1]} \\ {\color{magenta}Cut(2)} + \color{blue}{P[2]} \\ {\color{magenta}Cut(1)} + \color{blue}{P[3]} \\ {\color{magenta}Cut(0)} + \color{blue}{P[4]} \\ \end{cases}\] |
Cut(i): | 0 | ||||||||||
Length: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Run time: \(O(n^2)\)
|
|
|
|
|
Choices: | 0 | 1 | 1 | 2 | 4 | 3 | 4 | 1 | 2 | 4 | 3 |
Length: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|
|
|
|
Example to demo Choices[] only. Profit of 20 is not optimal! |
This is similar to the back link in Dijkstra’s shortest path algorithm
Prices: | 1 | 5 | 8 | 9 | 10 | 17 | 17 | 20 | 24 | 30 |
Length: | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
profit[i] | 0 | 1 | 5 | 8 | 10 | 13 | 17 | 18 | 22 | 25 | 30 |
choice[i] | 0 | 1 | 2 | 3 | 2 | 2 | 6 | 1 | 2 | 3 | 10 |
Readings in CLRS 4th edition: chapter 14, specifically 14.2
How many arithmetic operations are required to multiply a \(n \times m\) matrix by a \(m \times p\) matrix?
(don’t overthink this)
|
|
|
|
|
|
|
\(\times\) |
|
\(\times\) |
|
||||||||||||
|
|
\(\times\) |
|
\(\times\) |
|
||||||||||||
|
|
|
\(Best(1,n)\) = cheapest way to mult together \(M_1\) through \(M_n\)
\(Best(1,n)\) = cheapest way to mult together \(M_1\) through \(M_n\)
|
|||||||||||||||||||
|
|
|
|
\(Best(1,n)\) = cheapest way to mult together \(M_1\) through \(M_n\)
|
|||||||||||||||||||
|
|
|
|
\(Best(1,n)\) = cheapest way to mult together \(M_1\) through \(M_n\)
|
|
||||||||||||||||||
|
|
|
|
\(Best(1,n)\) = cheapest way to mult together \(M_1\) through \(M_n\)
|
|||||||||||||||||||
|
|
|
|
In general:
\(Best(i,j)\) = cheapest way to multiply together \(M_i\) through \(M_j\)
\(Best(i,j) = \min_{k=i}^{j-1} \left( {\color{green}Best(i,k)} + {\color{magenta}Best(k+1,j)}+r_ir_{k+1}c_j \right)\)
\(Best(i,i)=0\)
\(Best(1,n) = \min \begin{cases} {\color{green}Best(1,1)} + {\color{magenta}Best(2,n)} + r_1r_2c_n \\ {\color{green}Best(1,2)} + {\color{magenta}Best(3,n)} + r_1r_3c_n \\ {\color{green}Best(1,3)} + {\color{magenta}Best(4,n)} + r_1r_4c_n \\ {\color{green}Best(1,4)} + {\color{magenta}Best(5,n)} + r_1r_5c_n \\ \ldots \\ {\color{green}Best(1,n-1)} + {\color{magenta}Best(n,n)} + r_1r_nc_n \\ \end{cases}\)
In general:
\(Best(i,j)\) = cheapest way to multiply together \(M_i\) through \(M_j\)
\(Best(i,j) = \min_{k=i}^{j-1} \left( {\color{green}Best(i,k)} + {\color{magenta}Best(k+1,j)}+r_ir_{k+1}c_j \right)\)
\(Best(i,i)=0\)
\(Best(1,n) = \min \begin{cases} {\color{green}Best(1,1)} + {\color{magenta}Best(2,n)} + r_1r_2c_n \\ {\color{green}Best(1,2)} + {\color{magenta}Best(3,n)} + r_1r_3c_n \\ {\color{green}Best(1,3)} + {\color{magenta}Best(4,n)} + r_1r_4c_n \\ {\color{green}Best(1,4)} + {\color{magenta}Best(5,n)} + r_1r_5c_n \\ \ldots \\ {\color{green}Best(1,n-1)} + {\color{magenta}Best(n,n)} + r_1r_nc_n \\ \end{cases}\)
In general:
\(Best(i,j)\) = cheapest way to multiply together \(M_i\) through \(M_j\)
\(Best(i,j) = \min_{k=i}^{j-1} \left( \color{green}{Best(i,k)} + \color{magenta}{Best(k+1,j)}+r_ir_{k+1}c_j \right)\)
\(Best(i,i)=0\)
\(Best(1,n) = \min \begin{cases} {\color{green}Best(1,1)} + {\color{magenta}Best(2,n)} + r_1r_2c_n \\ {\color{green}Best(1,2)} + {\color{magenta}Best(3,n)} + r_1r_3c_n \\ {\color{green}Best(1,3)} + {\color{magenta}Best(4,n)} + r_1r_4c_n \\ {\color{green}Best(1,4)} + {\color{magenta}Best(5,n)} + r_1r_5c_n \\ \ldots \\ {\color{green}Best(1,n-1)} + {\color{magenta}Best(n,n)} + r_1r_nc_n \\ \end{cases}\)
|
\(\times\) |
|
\(\times\) |
|
\(\times\) |
|
\(\times\) |
|
\(\times\) |
|
\(\scriptsize Best(i,j) = \min_{k=i}^{j-1} \left( {\color{green}Best(i,k)} + {\color{magenta}Best(k+1,j)}+r_ir_{k+1}c_j \right)\)
\(\scriptsize Best(i,i)=0\)
|
|
\(\times\) |
|
\(\times\) |
|
\(\times\) |
|
\(\times\) |
|
\(\times\) |
|
\(\scriptsize Best(i,j) = \min_{k=i}^{j-1} \left( {\color{green}Best(i,k)} + {\color{magenta}Best(k+1,j)}+r_ir_{k+1}c_j \right)\)
\(\scriptsize Best(i,i)=0\)
\(\small Best(1,2) = \min\) \(\small \begin{cases} \ \\ \ \\ {\color{green}Best(1,1)} + {\color{magenta}Best(2,2)} + r_1r_2c_2 \\ \ \\ \ \\ \end{cases}\) |
|
|
\(\times\) |
|
\(\times\) |
|
\(\times\) |
|
\(\times\) |
|
\(\times\) |
|
\(\scriptsize Best(i,j) = \min_{k=i}^{j-1} \left( {\color{green}Best(i,k)} + {\color{magenta}Best(k+1,j)}+r_ir_{k+1}c_j \right)\)
\(\scriptsize Best(i,i)=0\)
\(\small Best(2,3) = \min\) \(\small \begin{cases} \ \\ \ \\ {\color{green}Best(2,2)} + {\color{magenta}Best(3,3)} + r_2r_3c_3 \\ \ \\ \ \\ \end{cases}\) |
|
|
\(\times\) |
|
\(\times\) |
|
\(\times\) |
|
\(\times\) |
|
\(\times\) |
|
\(\scriptsize Best(i,j) = \min_{k=i}^{j-1} \left( {\color{green}Best(i,k)} + {\color{magenta}Best(k+1,j)}+r_ir_{k+1}c_j \right)\)
\(\scriptsize Best(i,i)=0\)
|
|
\(\times\) |
|
\(\times\) |
|
\(\times\) |
|
\(\times\) |
|
\(\times\) |
|
\(\scriptsize Best(i,j) = \min_{k=i}^{j-1} \left( {\color{green}Best(i,k)} + {\color{magenta}Best(k+1,j)}+r_ir_{k+1}c_j \right)\)
\(\scriptsize Best(i,i)=0\)
\(r_1r_2c_3=30 \cdot 35 \cdot 5=5250\) \(r_1r_3c_3=30 \cdot 15 \cdot 5=2250\)
\(\small Best(1,3) = \min\) \(\small Best(1,3) = \min\) |
|
|
\(\times\) |
|
\(\times\) |
|
\(\times\) |
|
\(\times\) |
|
\(\times\) |
|
\(\scriptsize Best(i,j) = \min_{k=i}^{j-1} \left( {\color{green}Best(i,k)} + {\color{magenta}Best(k+1,j)}+r_ir_{k+1}c_j \right)\)
\(\scriptsize Best(i,i)=0\)
To find \(Best(i,j)\): need all preceeding terms of row \(i\) and column \(j\) (In other words, everything below and to the left) Conclusion: solve in order of diagonal |
|
|
\(\times\) |
|
\(\times\) |
|
\(\times\) |
|
\(\times\) |
|
\(\times\) |
|
\(\scriptsize Best(i,j) = \min_{k=i}^{j-1} \left( {\color{green}Best(i,k)} + {\color{magenta}Best(k+1,j)}+r_ir_{k+1}c_j \right)\)
\(\scriptsize Best(i,i)=0\)
\(\small Best(1,6) = \min\) |
|
|
\(\Theta(n^2)\) cells in the array
\(\Theta(n)\) options for each cell
(\(n\) is the number of matrices) |
|
|
\(\Theta(n^3)\) overall run time |
“Remember” which choice of \(k\) was the minimum at each cell
\(\scriptsize Best(i,j) = \min_{k=i}^{j-1} \left( {\color{green}Best(i,k)} + {\color{magenta}Best(k+1,j)}+r_ir_{k+1}c_j \right)\)
\(\scriptsize Best(i,i)=0\)
\(\small Best(1,6) = \min\) \(\small \begin{cases} {\color{green}Best(1,1)} + {\color{magenta}Best(2,6)} + r_1r_2c_6 \\ {\color{green}Best(1,2)} + {\color{magenta}Best(3,6)} + r_1r_3c_6 \\ {\color{red}Best(1,3) + Best(4,6) + r_1r_4c_6} \\ {\color{green}Best(1,4)} + {\color{magenta}Best(5,6)} + r_1r_5c_6 \\ {\color{green}Best(1,5)} + {\color{magenta}Best(6,6)} + r_1r_6c_6 \\ \end{cases}\) |
|
( |
|
\(\times\) | ( |
|
\(\times\) |
|
) | ) | \(\times\) | ( | ( |
|
\(\times\) |
|
) | \(\times\) |
|
) |
\(\scriptsize Best(i,j) = \min_{k=i}^{j-1} \left( {\color{green}Best(i,k)} + {\color{magenta}Best(k+1,j)}+r_ir_{k+1}c_j \right)\)
\(\scriptsize Best(i,i)=0\)
\(\small Best(1,6) = \min\) \(\small \begin{cases} {\color{green}Best(1,1)} + {\color{magenta}Best(2,6)} + r_1r_2c_6 \\ {\color{green}Best(1,2)} + {\color{magenta}Best(3,6)} + r_1r_3c_6 \\ {\color{green}Best(1,3)} + {\color{magenta}Best(4,6)} + r_1r_4c_6 \\ {\color{green}Best(1,4)} + {\color{magenta}Best(5,6)} + r_1r_5c_6 \\ {\color{green}Best(1,5)} + {\color{magenta}Best(6,6)} + r_1r_6c_6 \\ \end{cases}\) |
|
Readings in CLRS 4th edition: chapter 14
Remember change making?
Given access to unlimited quantities of pennies, nickels, dimes, toms, and quarters (worth value 1, 5, 10, 11, 25 respectively), give 90 cents change using the fewest number of coins.
|
|
Observation: We can rewrite this to take \(\lfloor n/c \rfloor\) copies of the next largest coin at each step, and reduce \(x\) by \(c \cdot \lfloor n/c \rfloor\). Also avoid call to max() by choosing next \(c_i\) from largest to smallest (sort \(C\) first).
90 cents
|
|
|
|
90 cents
\(Change(n)\): minimum number of coins needed to give change for \(n\) cents
Possibilities for last coin |
Coins needed | When to do |
---|---|---|
\(Change(n-25)+1\) | if \(n \ge 25\) | |
\(Change(n-11)+1\) | if \(n \ge 11\) | |
\(Change(n-10)+1\) | if \(n \ge 10\) | |
\(Change(n-5)+1\) | if \(n \ge 5\) | |
\(Change(n-1)+1\) | if \(n \ge 1\) |
\(Change(n)\): minimum number of coins needed to give change for cents
\[Change(n) = \min \begin{cases} Change(n-25)+1 \text{ if } n \ge 25 \\ Change(n-11)+1 \text{ if } n \ge 11 \\ Change(n-10)+1 \text{ if } n \ge 10 \\ Change(n-5)+1 \text{ if } n \ge 5 \\ Change(n-1)+1 \text{ if } n \ge 1 \\ \end{cases}\] |
|
Base Case: \(Change(0)=0\) |
|||
Running time: \(O(k \cdot n)\) |
Is this efficient? |
|
|
\(k\) is the number of coins |
No, this is pseudo-polynomial time |
Readings in CLRS 4th edition: chapter 14
Method for image resizing that doesn’t scale/crop the image
Removes a “block” of pixels
|
→ |
|
Removes “stripes” of pixels
|
→ |
|
(There are more visually pleasing ways to scale images)
Removes “least energy seam” of pixels
https://trekhleb.dev/js-image-carver/
|
→ |
|
Method for image resizing that doesn’t scale/crop the image
Cropped | Scaled | Carved |
---|---|---|
Let \({\color{red}S(i,j)}=\) least energy seam from the bottom of the image up to pixel \(p_{i,j}\) |
formula |
\(p_{i,j}\)
\(p_{n,k}\) |
||
\(m\) |
Assume we know the least energy seams for all of row \(n-1\) (i.e., we know \(S(n-1,\ell)\) for all \(\ell\)) |
Known through \(n-1\) |
\(p_{i,j}\)
\(p_{n,k}\) |
||
\(m\) |
Assume we know the least energy seams for all of row \(n-1\) (i.e., we know \(S(n-1,\ell)\) for all \(\ell\))
\(p_{n,k}\) | |||||
|
|
|
|||
|
|
|
\[{\color{red}S(n,k)} = \min \begin{cases} {\color{blue}S(n-1,k-1)} & + e(p_{n,k}) \\ {\color{purple}S(n-1,k)} & + e(p_{n,k}) \\ {\color{magenta}S(n-1,k+1)} & + e(p_{n,k}) \\ \end{cases}\]
Want to delete the least energy seam going from bottom to top, so delete: \(\min_{k=1}^m({\color{red}S(n,k)})\) |
\(n\) |
\(p_{i,j}\)
\(p_{n,k}\) |
||
\(m\) |
Assume we know the least energy seams for all of row \(n-1\) (i.e., we know \(S(n-1,\ell)\) for all \(\ell\))
\(p_{n,k}\) | |||||
|
|
|
|||
|
|
|
\[{\color{red}S(n,k)} = \min \begin{cases} {\color{blue}S(n-1,k-1)} & + e(p_{n,k}) \\ {\color{purple}S(n-1,k)} & + e(p_{n,k}) \\ {\color{magenta}S(n-1,k+1)} & + e(p_{n,k}) \\ \end{cases}\]
Want to delete the least energy seam going from bottom to top, so delete: \(\min_{k=1}^m({\color{red}S(n,k)})\) |
\(n\) |
\(p_{i,j}\)
\(p_{n,k}\) |
||
\(m\) |
Start from bottom of image (row 1), solve up to top | |
Initialize \(S(1,k)=e(p_{1,k})\) for each pixel in row 1 | \(\color{green}\Theta(m)\) |
For \(i \ge 2\) find \({\color{red}S(n,k)} = \min \begin{cases} {\color{purple}S(n-1,k-1)} & + e(p_{i,k}) \\ {\color{blue}S(n-1,k)} & + e(p_{i,k}) \\ {\color{magenta}S(n-1,k+1)} & + e(p_{i,k}) \\ \end{cases}\) | \(\color{red}\Theta(n \cdot m)\) |
Pick min \(\color{red}S(n,k)\) from top row, backtrack, deleting pixels | \(\Theta(n+m)\) |
Energy of the seam initialized to the energy of that pixel |
Start from bottom of image (row 1), solve up to top | |
Initialize \(S(1,k)=e(p_{1,k})\) for each pixel \(p_{1,k}\) | \(\color{green}\Theta(m)\) |
For \(i \ge 2\) find \({\color{red}S(i,k)} = \min \begin{cases} {\color{purple}S(i-1,k-1)} & + e(p_{i,k}) \\ {\color{blue}S(i-1,k)} & + e(p_{i,k}) \\ {\color{magenta}S(i-1,k+1)} & + e(p_{i,k}) \\ \end{cases}\) | \(\color{red}\Theta(n \cdot m)\) |
Pick min \(\color{red}S(n,k)\) from top row, backtrack, deleting pixels | \(\Theta(n+m)\) |
Energy of the seam initialized to the energy of that pixel |
Start from bottom of image (row 1), solve up to top | |
Initialize \(S(1,k)=e(p_{1,k})\) for each pixel \(p_{1,k}\) | \(\color{green}\Theta(m)\) |
For \(i \ge 2\) find \({\color{red}S(i,k)} = \min \begin{cases} {\color{purple}S(i-1,k-1)} & + e(p_{i,k}) \\ {\color{blue}S(i-1,k)} & + e(p_{i,k}) \\ {\color{magenta}S(i-1,k+1)} & + e(p_{i,k}) \\ \end{cases}\) | \(\color{red}\Theta(n \cdot m)\) |
Pick min \(\color{red}S(n,k)\) from top row, backtrack, deleting pixels | \(\Theta(n+m)\) |
Energy of the seam initialized to the energy of that pixel |
Start from bottom of image (row 1), solve up to top | |
Initialize \(S(1,k)=e(p_{1,k})\) for each pixel \(p_{1,k}\) |
\(\color{green}\Theta(m)\) |
For \(i \ge 2\) find \({\color{red}S(i,k)} = \min \begin{cases} {\color{purple}S(i-1,k-1)} & + e(p_{i,k}) \\ {\color{blue}S(i-1,k)} & + e(p_{i,k}) \\ {\color{magenta}S(i-1,k+1)} & + e(p_{i,k}) \\ \end{cases}\) |
\(\color{red}\Theta(n \cdot m)\) |
Pick min \(\color{red}S(n,k)\) from top row, backtrack, deleting pixels |
\(\Theta(n+m)\) |
Energy of the seam initialized to the energy of that pixel |
Only need to update pixels dependant on the removed seam
\(2n\) pixels change |
\(\Theta(2n)\) time to update pixels |
\(\Theta(n+m)\) to find min+backtrack |
Readings in CLRS 4th edition: chapter 14, specifically 14.4
Given two sequences \(X\) and \(Y\), find the length of their longest common subsequence
Example: |
Brute force: compare every subsequence of \(X\) with \(Y\): \(\Omega(2^n)\)
Let \(LCS(i.j)=\) length of the LCS for the first \(i\) characters of \(X\), first \(j\) characters of \(Y\)
Find \(\color{magenta}LCS(i,j)\):
Case 1: \(\color{magenta}X[i]=Y[j]\) |
X = ATCTGCGT |
\(LCS(i,j)=LCS(i-1,j-1)+1\) |
|
Case 2: \(\color{magenta}X[i]\ne Y[j]\) | |
X = ATCTGCGA |
X = ATCTGCGT |
\(LCS(i,j)=LCS(i,j-1)\) |
\(LCS(i,j)=LCS(i-1,j)\) |
\[LCS(i,j) = \begin{cases} 0 & \text{if } i=0 \text{ or } j=0 \\ {\color{green}LCS(i-1,j-1)+1} & \text{if } X[i]=Y[j] \\ {\color{blue}\max(LCS(i,j-1),LCS(i-1,j))} & \text{otherwise} \\ \end{cases}\]
We need two functions; one will be recursive
|
|
\[\scriptstyle LCS(i,j) = \begin{cases} 0 & \text{if } i=0 \text{ or } j=0 \\ {\color{green}LCS(i-1,j-1)+1} & \text{if } X[i]=Y[j] \\ {\color{blue}\max(LCS(i,j-1),LCS(i-1,j))} & \text{otherwise} \\ \end{cases}\]
To fill in cell \((i,j)\) we need cells \((i-1,j-1)\), \((i-1,j)\), and \((i,j-1)\) Fill from top → bottom, left → right (with any preference)
\[\scriptstyle LCS(i,j) = \begin{cases} 0 & \text{if } i=0 \text{ or } j=0 \\ {\color{green}LCS(i-1,j-1)+1} & \text{if } X[i]=Y[j] \\ {\color{blue}\max(LCS(i,j-1),LCS(i-1,j))} & \text{otherwise} \\ \end{cases}\]
Run time: \(\Theta(n \cdot m)\) (for \(|X|=n\), \(|Y|=m\))
\[\scriptstyle LCS(i,j) = \begin{cases} 0 & \text{if } i=0 \text{ or } j=0 \\ {\color{green}LCS(i-1,j-1)+1} & \text{if } X[i]=Y[j] \\ {\color{blue}\max(LCS(i,j-1),LCS(i-1,j))} & \text{otherwise} \\ \end{cases}\]
Start from bottom right,
if symbols matched, print that symbol then go diagonally,
else go to largest adjacent
\[\scriptstyle LCS(i,j) = \begin{cases} 0 & \text{if } i=0 \text{ or } j=0 \\ {\color{green}LCS(i-1,j-1)+1} & \text{if } X[i]=Y[j] \\ {\color{blue}\max(LCS(i,j-1),LCS(i-1,j))} & \text{otherwise} \\ \end{cases}\]
Start from bottom right,
if symbols matched, print that symbol then go diagonally,
else go to largest adjacent
\[\scriptstyle LCS(i,j) = \begin{cases} 0 & \text{if } i=0 \text{ or } j=0 \\ {\color{green}LCS(i-1,j-1)+1} & \text{if } X[i]=Y[j] \\ {\color{blue}\max(LCS(i,j-1),LCS(i-1,j))} & \text{otherwise} \\ \end{cases}\]
Start from bottom right,
if symbols matched, print that symbol then go diagonally,
else go to largest adjacent
Readings in CLRS 4th edition: chapter 14
|
Math and CS professors have been asked to testify in court as to the difficulty in creating some of these districts
https://www.heinz.cmu.edu/media/2018/ |
“Wesley Pegden, professor of mathematical sciences at Carnegie Mellon University, proved that Pennsylvania’s congressional map was a partisan gerrymander—in fact, he showed that if you made trillions of districtings by making small random perturbations to the map, 99.9999999% of them of them would be fairer than the existing map, a property which is mathematically impossible to be typical for a Congressional districting, regardless of the political geography of a state. His expert testimony during a lawsuit led to the Pennsylvania supreme court throwing out the old map.” https://www.heinz.cmu.edu/media/2018/October/wes-pegden-gerrymandering |
|
|
|
|
|
|
|
|
|
|
\(S(j,k,x,y) = \text{True}\) |
if from among the first \(j\) precincts: \(k\) are assigned to \(\color{magenta}D_1\) exactly \(x\) vote for R in \(\color{magenta}D_1\) exactly \(y\) vote for R in \(\color{green}D_2\) |
|
\(\color{red}n \times n \times mn \times mn\) |
||
4D Dynamic programming! |
|
|
|
|
|
\[S(j,k,x,y) = {\color{magenta}S(j-1,k-1,x-S(p_j),y)} \vee {\color{green}S(j-1,k,x,y-S(p_j))}\]
\[\small S(j,k,x,y) = {\color{magenta}S(j-1,k-1,x-S(p_j),y)} \vee {\color{green}S(j-1,k,x,y-S(p_j))}\]
|
|
|
\[\begin{align} S(j,k,x,y) = & {\color{magenta}S(j-1,k-1,x-S(p_j),y)} \vee \\ & {\color{green}S(j-1,k,x,y-S(p_j))} \end{align}\] |
||
Search for True entry at \(S \left( n, \frac{n}{2}, >\frac{m \cdot n}{4}, >\frac{m \cdot n}{4} \right)\) |
\[\small S(j,k,x,y) = {\color{magenta}S(j-1,k-1,x-S(p_j),y)} \vee {\color{green}S(j-1,k,x,y-S(p_j))}\]
|
|
\[\begin{align} S(j,k,x,y) = & {\color{magenta}S(j-1,k-1,x-S(p_j),y)} \vee \\ & {\color{green}S(j-1,k,x,y-S(p_j))} \end{align}\] |
|
Total run time: \(\Theta(n^4m^2)\) |