程序代写案例-CSE 101

欢迎使用51辅导,51作业君孵化低价透明的学长辅导平台,服务保持优质,平均费用压低50%以上! 51fudao.top
CSE 101
Algorithm Design & Analysis
Lecture 6
Today’s plan
Dynamic programming:
- Knapsack (with and without repetition)
- Independen
t sets in trees - if time
- String interleaving (homework 1) - if time
Knapsack
Suppose that you have a bag that can store up to 15lbs. You go into a store
that has the following 4 kinds of items, each with a weight and a value:
- Item 1: weight 9lbs, value $45
- Item 2: weight 5lbs, value $30
- Item 3: weight 6lbs, value $32
- Item 4: weight 3lbs, value $15
Assume that you’re allowed to take any number of each items, as long as they
all fit in your bag. How would you pick the items to maximize the total value?
How about if you’re only allowed to take at most one of each item?
Knapsack
A burglar has broken into a store. The store items 1…n, where item i has
weight wi and value vi. The burglar has a knapsack with capacity C. The burglar
can take as many items as they want, as long as the weight of all items doesn’t
exceed the knapsack capacity C. Which items should the burglar take to
maximize the total value, assuming:
- Each type of item has unlimited copies? (with repetition)
- Each type of item only has one copy? (without repetition)
Knapsack with repetition
Question: At each step, which type of item does the burglar take? Assume
capacity 15lbs.
- Item 1: weight 9lbs, value $45
- Item 2: weight 5lbs, value $30
- Item 3: weight 6lbs, value $32
- Item 4: weight 3lbs, value $15
Knapsack with repetition
C
{1,2,...,n}
C - w1
{1,2,...,n}
C - w2
{1,2,...,n}
C - wn
{1,2,...,n}

C - w1 - w1
{1,2,...,n}
C - w1 - w2
{1,2,...,n}
C - w2 - w1
{1,2,...,n}

C - w2 - w2
{1,2,...,n}
C - wn - wn
{1,2,...,n}

… … … … …
Knapsack with repetition
C
{1,2,...,n}
C - w1
{1,2,...,n}
C - w2
{1,2,...,n}
C - wn
{1,2,...,n}

C - w1 - w1
{1,2,...,n}
C - w1 - w2
{1,2,...,n}
C - w2 - w1
{1,2,...,n}

C - w2 - w2
{1,2,...,n}
C - wn - wn
{1,2,...,n}

… … … … …
Same subproblem!
Knapsack with repetition
C
{1,2,...,n}
C - w1
{1,2,...,n}
C - w2
{1,2,...,n}
C - wn
{1,2,...,n}

C - w1 - w1
{1,2,...,n}
C - w1 - w2
{1,2,...,n}
C - w2 - w1
{1,2,...,n}

C - w2 - w2
{1,2,...,n}
C - wn - wn
{1,2,...,n}

… … … … …
What is changing between each recursive call?
Knapsack with repetition
C
{1,2,...,n}
C - w1
{1,2,...,n}
C - w2
{1,2,...,n}
C - wn
{1,2,...,n}

C - w1 - w1
{1,2,...,n}
C - w1 - w2
{1,2,...,n}
C - w2 - w1
{1,2,...,n}

C - w2 - w2
{1,2,...,n}
C - wn - wn
{1,2,...,n}

… … … … …
Each recursive call, we want the max value by taking from items 1…n for some
changing max capacity. This is a rephrasing of the original problem!
Knapsack with repetition
1. Subproblems
Let K[i] be the max value we can get from items 1…n (with repetition) with a
knapsack of capacity i.
Knapsack with repetition
2. Base case(s)
Which subproblem(s) can we solve independently (without needing results
from other subproblems)?
Knapsack with repetition
2. Base case(s)
K[0] = 0. If the knapsack has capacity 0, we can’t put anything in it.
Knapsack with repetition
3. Recurrence relation
How do we solve K[i] for any general value of i?
i
{1,2,...,n}
i - w1
{1,2,...,n}
i - w2
{1,2,...,n}
i - wn
{1,2,...,n}

i - w3
{1,2,...,n}
Knapsack with repetition
3. Recurrence relation
Which item do we take?
- Case 0: If we don’t take any item, K[i] = 0
- Case 1: If we take item 1, K[i] = v1 + K[i - w1] (if w1 ≤ i)
- Case 2: If we take item 2, K[i] = v2 + K[i - w2] (if w2 ≤ i)
- …
- Case n: If we take item n, K[i] = vn + K[i - wn] (if wn ≤ i)
Which case do we take?
Knapsack with repetition
3. Recurrence relation
We take the case with the largest resulting value. So to summarize:
K[i] = max1 ≤ j ≤ n, w_j ≤ i (vj + K[i - wj])
Knapsack with repetition
4. Ordering the subproblems
Which subproblem(s) does each K[i] depend on?
K[0] K[1] K[2] K[3] K[4] … K[i-1] K[i] … K[C]
Knapsack with repetition
4. Ordering the subproblems
Each K[i] depends on all K[0]...K[i-1]. So we should solve the subproblems for
increasing values of i (left to right in the array K).
K[0] K[1] K[2] K[3] K[4] … K[i-1] K[i] … K[C]
Knapsack with repetition
5. Final output
Which subproblem(s) correspond with the answer we want?
Knapsack with repetition
5. Final output
K[C], “the max value we can get from items 1…n (with repetition) with a
knapsack of capacity C.”
Knapsack with repetition
6. Pseudocode
KnapsackWithRepetition(C, w[1…n], v[1…n]):
Declare K[0…C]. Let K[0] = 0
For i = 1…C:
K[i] = 0
For j = 1…n:
If w[j] ≤ i, K[i] = max(K[i], v[j] + K[i - w[j])
Return K[C]
Knapsack with repetition
7. Runtime
Runtime of DP: (number of subproblems)(time per subproblem) + overhead
- Number of subproblems:
- Time per subproblem:
- Overhead:
Knapsack with repetition
7. Runtime
Runtime of DP:
- Number of subproblems: O(C) for all K[i], 0 ≤ i ≤ C
- Time per subproblem: O(n) to check all n items
- Overhead: O(C) to declare array, O(1) to return
Overall: O(nC)
Knapsack without repetition
Recall the question for the case with repetition: At each step, which type of
item does the burglar take? Assume capacity 15lbs.
- Item 1: weight 9lbs, value $45
- Item 2: weight 5lbs, value $30
- Item 3: weight 6lbs, value $32
- Item 4: weight 3lbs, value $15
Will this approach still be efficient when there is no repetition?
Knapsack without repetition
C
{1,2,...,n}
C - w1
{2,...,n}
C - w2
{1,3,...,n}
C - wn
{1,2,...,n-1}

C - w1 - w2
{3,...,n}
C - w1 - w3
{2,4,...,n}
C - w2 - w1
{3,...,n}

C - w2 - w3
{1,4,...,n}
C - wn - wn-1
{1,2,...,n-2}

… … … … …
Knapsack without repetition
C
{1,2,...,n}
C - w1
{2,...,n}
C - w2
{1,3,...,n}
C - wn
{1,2,...,n-1}

C - w1 - w2
{3,...,n}
C - w1 - w3
{2,4,...,n}
C - w2 - w1
{3,...,n}

C - w2 - w3
{1,4,...,n}
C - wn - wn-1
{1,2,...,n-2}

… … … … …
We note that while capacities can range from 0…C, the set of items available
can be any subset of {1…n}, and there is an exponential number of subsets.
Knapsack without repetition
We see that the approach of asking which item to take will result in an
exponential number of subproblems.
However, we note the following:
- If we take item n, then we have value vn, and we now consider items 1…n-
1 and capacity C - wn
- If we don’t take item n, then we consider items 1…n-1 and capacity C
Knapsack without repetition
In both cases, we want the max value from items 1…n-1 and some max
capacity. This is a rephrasing of the original problem!
So now, we change the question to ask: At each step, does the burglar take
the last item?
Knapsack without repetition
C
{1,2,...,n}
C - wn
{1,2,...,n-1}
C
{1,2,...,n-1}
C - wn - wn-1
{1,2,...,n-2}
C - wn
{1,2,...,n-2}
C - wn-1
{1,2,...,n-2}
C
{1,2,...,n-2}
… … … …
Knapsack without repetition
C
{1,2,...,n}
C - wn
{1,2,...,n-1}
C
{1,2,...,n-1}
C - wn - wn-1
{1,2,...,n-2}
C - wn
{1,2,...,n-2}
C - wn-1
{1,2,...,n-2}
C
{1,2,...,n-2}
… … … …
Same subproblem if
wn = wn-1!
Knapsack without repetition
C
{1,2,...,n}
C - wn
{1,2,...,n-1}
C
{1,2,...,n-1}
C - wn - wn-1
{1,2,...,n-2}
C - wn
{1,2,...,n-2}
C - wn-1
{1,2,...,n-2}
C
{1,2,...,n-2}
… … … …
We note that now, every recursive calls have the form “max value for items
1…i (without repetition) and some changing max capacity.” We’ve improved
the number of different subsets considered from exponential to linear!
Knapsack without repetition
1. Subproblems
Let K[i, j] be the max value we can get from items 1…i (without repetition) with
a knapsack of capacity j.
Knapsack without repetition
2. Base case(s)
Which subproblem(s) can we solve independently (without needing results
from other subproblems)?
Knapsack without repetition
2. Base case(s)
K[i, 0] = 0 for all 0 ≤ i ≤ n. If the knapsack has capacity 0, we can’t put anything
in it.
K[0, j] = 0 for all 0 ≤ j ≤ C. If there are no items, we can’t take anything
regardless of knapsack size.
Knapsack without repetition
3. Recurrence relation
How do we solve K[i, j] for any general value of i, j?
j
{1,2,...,i}
j - wi
{1,2,...,i-1}
j
{1,2,...,i-1}
Knapsack without repetition
3. Recurrence relation
Which item do we take?
- Case 1: If we don’t take item i, K[i, j] = K[i-1, j]
- Case 2: If we take item i, K[i, j] = vi + K[i-1, j - wi] (if wi ≤ j)
Which case do we take?
Knapsack without repetition
3. Recurrence relation
We take the case with the largest resulting value. So to summarize:
If wi > j, K[i, j] = K[i-1, j]
Else, K[i, j] = max(K[i-1, j], vi + K[i-1, j - wi]
Knapsack without repetition
4. Ordering the subproblems
Which subproblem(s) does each K[i, j] depend on?
… … … … … … … … … …
K[i-1, 0] K[i-1, 1] K[i-1, 2] K[i-1, 3] K[i-1, 4] … K[i-1,j-1] K[i-1, j] … K[i-1, C]
K[i, 0] K[i, 1] K[i, 2] K[i, 3] K[i, 4] … K[i, j-1] K[i, j] … K[i, C]
… … … … … … … … … …
Knapsack without repetition
4. Ordering the subproblems
Each K[i, j] depends on 2 cells on the row before it. So we should solve the
subproblems in order of each row from top to bottom (for each row we can
solve left to right).
… … … … … … … … … …
K[i-1, 0] K[i-1, 1] K[i-1, 2] K[i-1, 3] K[i-1, 4] … K[i-1,j-1] K[i-1, j] … K[i-1, C]
K[i, 0] K[i, 1] K[i, 2] K[i, 3] K[i, 4] … K[i, j-1] K[i, j] … K[i, C]
… … … … … … … … … …
Knapsack without repetition
5. Final output
Which subproblem(s) correspond with the answer we want?
Knapsack without repetition
5. Final output
K[n, C], “the max value we can get from items 1…n (without repetition) with a
knapsack of capacity C.”
Knapsack without repetition
6. Pseudocode
KnapsackWithoutRepetition(C, w[1…n], v[1…n]):
Declare K[0,...n, 0…C].
Let K[0, j] = K[i, 0] = 0 for all 0 ≤ i ≤ n, 0 ≤ j ≤ C.
For i = 1…n:
For j = 1…C:
If w[i] > j, K[i, j] = K[i-1, j]
Else, K[i, j] = max(K[i-1, j], v[i] + K[i-1, j - w[i])
Return K[n, C]
Knapsack without repetition
7. Runtime
Runtime of DP: (number of subproblems)(time per subproblem) + overhead
- Number of subproblems:
- Time per subproblem:
- Overhead:
Knapsack without repetition
7. Runtime
Runtime of DP:
- Number of subproblems: O(nC) for all K[i, j], 0 ≤ i ≤ n, 0 ≤ j ≤ C.
- Time per subproblem: O(1) to check 2 cells in the table K
- Overhead: O(nC) to declare array, O(1) to return
Overall: O(nC)
Knapsack runtime
We observed that the runtime of both versions of knapsack is O(nC). This is in
fact not polynomial time!
When we consider linearly increasing size of the input, for the number of
items, that would go from n, n+1, n+2,... For the capacity, the size is actually
the number of bits of C, which is x = log(C), x+1, x+2,...
Since knapsack’s runtime grows in terms of the value of C and not the size of
C, it is not polynomial time. Knapsack’s runtime is in a class known as pseudo-
polynomial, and the knapsack problem is actually NP-complete.
Max independent set
Given a graph G(V, E), an independent set is a subset S ⊆ V such that for all
edges (u, v) ⊆ E, u ∉ S or v ∉ S. We want to find the largest independent set.
A
B
C
D E
F
Max independent set
Determining the largest independent set of any graph also turns out to be NP-
complete.
However, if the graph is a tree, we can take advantage of the structure of trees
to improve the runtime.
How? With dynamic programming!
Max independent set of a tree
We want to find the max independent set of the
tree rooted at A.
What decision can we try making to know which
vertices will be in the independent set?
A
B C D
E F G
H
Max independent set of a tree
If A is in the independent set S, then what is the
size of the max independent set?
If A is not in S, then what is the size of the
max independent set?
A
B C D
E F G
H
Max independent set of a tree
We see that in both cases, we need to find the max
independent set of various subtrees of the tree
rooted at A.
A
B C D
E F G
H
Max independent set of a tree
1. Subproblems
Let I[u] be the max independent set of the tree rooted at vertex u
Max independent set of a tree
2. Base case(s)
Max independent set of a tree
2. Base case(s)
I[u] = 1 if u is a leaf
Max independent set of a tree
3. Recurrence relation
Recall the 2 cases we discussed
A
B C D
E F G
Max independent set of a tree
3. Recurrence relation
Case 1: u is in the max independent set. I[u] = 1 + ∑ w grandchildren of u I[w]
Case 2: u is not in the max independent set. I[u] = ∑ x children of u I[x]
We take the max of the 2 cases. Therefore:
I[u] = max(1 + ∑ w grandchildren of u I[w], ∑ x children of u I[x])
Max independent set of a tree
4. Ordering the subproblems
Which subproblem(s) does each I[u] depend on?
Max independent set of a tree
4. Ordering the subproblems
Each I[u] depends on I[v], where v is either u’s children or grandchildren. So
we should solve the subproblems in order of each tree level from bottom to
top.
Max independent set of a tree
5. Final output
Which subproblem(s) correspond with the answer we want?
Max independent set of a tree
5. Final output
I[v], “the max independent set of the tree rooted at vertex v.”
Max independent set of a tree
6. Pseudocode
MaxIndependentSet(G(V, E), root v): (assume V ordered in levels bottom up)
Declare K[m] for all m ∈ V
For each u ∈ V:
If u is a leaf: I[u] = 1
Else, I[u] = max(1 + ∑ w grandchildren of u I[w], ∑ x children of u I[x])
Return I[v]
Max independent set of a tree
7. Runtime
Runtime of DP:
- Number of subproblems: |V|
- Time per subproblem: |children of u| + |grandchildren of u|
- Overhead: O(|V|) to declare array
Overall: O(|V|)
Interleaving string
Given 3 strings x (length n), y (length m), and z (length n+m), determine if z is
an interleaving of x and y.
Backtracking algorithm:
BTInterleaving(x1…xn, y1...ym, z1...zn+m):
If n = 0, return TRUE if y1...ym = z1...zm, else return FALSE
If m = 0, return TRUE if x1...xn = z1...zn, else return FALSE
If x1 = z1 and BTInterleaving(x2…xn, y1...ym, z2...zn+m), return TRUE
If y1 = z1 and BTInterleaving(x1…xn, y2...ym, z2...zn+m), return TRUE
Return FALSE
Interleaving string
a) Draw the recursion tree for x = 1010, y = 0011, z = 10001101
x = 1010
y = 0011
z = 10001101
x = 010
y = 0011
z = 0001101
x = 10
y = 0011
z = 001101
x = 010
y = 011
z = 001101
x = 10
y = 011
z = 01101
x = 10
y = 11
z = 1101
x = 0
y = 11
z = 101
x = 0
y = 1
z = 01
x =
y = 1
z = 1
x = 10
y = 1
z = 101
x = 0
y = 1
z = 01
x =
y = 1
z = 1
x = 10
y =
z = 01
x = 10
y = 011
z = 01101
x = 010
y = 11
z = 01101
x = 10
y = 11
z = 1101
x = 10
y = 11
z = 1101


Interleaving string
b) What is an upper bound on the total number of recursive calls this
algorithm might make? (in terms of n and m)
If x1 = y1 = z1, then the function makes both recursive calls. If this happens
every time, then we’ll always make 2 recursive calls. We might only use 1 digit
from z each time, so the recursion tree has n+m levels, and each level doubles
the number of recursive calls from the last in the worst case.
Overall an upper bound for the number of recursive calls is 2n+m
Interleaving string
c) What are the subproblems?
We see that between each recursive calls, the first character of x and y may
change. We define IS[i, j] = if xi…xn and yj…ym is an interleaving of zn+m-i-j+2…zn+m.
Alternatively you can use the last character of x and y. We define IS[i, j] = if
x1…xi and y1…yj is an interleaving of z1…zi+j. We’ll use this convention to
simplify notation, though we note that simple modifications can make the
other convention work as well.
Interleaving string
c) What is the algorithm?
Base case(s):
- IS[0, 0] = TRUE (this is when both x and y are empty)
- IS[0, j] = TRUE if y1…yj = z1…zj, else IS[0, j] = FALSE (for all 1 ≤ j ≤ m)
- IS[i, 0] = TRUE if x1…xi = z1…zi, else IS[i, 0] = FALSE (for all 1 ≤ i ≤ n)
Recurrence relation:
- IS[i, j] = TRUE if (xi = zi+j and IS[i-1, j]) or (yj = zi+j and IS[i, j-1]). Else IS[i, j] =
FALSE
Interleaving string
Ordering of subproblems:
- We note that IS[i, j] depends on IS[i-1, j] and IS[i, j-1], so we solve the
problems by rows top to bottom, and in each row we solve left to right
(for i=1…n; for j=1…m)
Final output:
- IS[n, m]
… … … …
… IS[i-1, j-1] IS[i-1, j] …
… IS[i, j-1] IS[i, j] …
… … … …
Interleaving string
Pseudocode (THIS IS THE ONLY PART YOU NEED FOR THE HOMEWORK):
StringInterleaving(x[1…n], y[1…m], z[1…n+m]):
Declare IS[0…n, 0…m]. Let IS[0, 0] = TRUE
For i = 1…n: If x1…xi = z1…zi then IS[i, 0] = TRUE. Else IS[i, 0] = FALSE
For j = 1…m: If y1…yj = z1…zj then IS[0, j] = TRUE. Else IS[0, j] = FALSE
For i = 1…n:
For j = 1…m:
If (xi = zi+j and IS[i-1, j]) or (yj = zi+j and IS[i, j-1]) then
IS[i, j] = TRUE
Else IS[i, j] = FALSE
Return IS[n, m]
Interleaving string
e) What is the runtime?
- Number of subproblems: O(nm)
- Time per subproblem: O(1)
- Overhead: O(nm) to create array, O(1) to return
Overall: O(nm)
Any questions?
Thank you!

欢迎咨询51作业君
51作业君

Email:51zuoyejun

@gmail.com

添加客服微信: abby12468