Vous êtes sur la page 1sur 4

Solutions to Homework Ten CSE 101

1. For graph G = (V, E) with edge weights w(), you already have a minimum spanning tree T = (V, E

).
Then the weight of an edge e increases. How should T be updated?
Case 1: e E

. Nothing to do.
Case 2: e E

. In this case, remove e from T; this divides the tree in two, with vertices V
1
on one side
and V
2
= V V
1
on the other. Find the lightest edge (in E) between V
1
and V
2
and add it in. The
total time taken is O(|V | +|E|).
2. We are given points x
1
, . . . , x
n
on the line, as well as intervals [s
1
, e
1
], . . . , [s
m
, e
m
]. The goal is to nd
the minimum number of intervals that cover all the x
i
.
Heres the idea: suppose you sort the points so that x
1
x
2
x
n
. You have to cover x
1
, so you
might as well begin by picking the interval that covers it and as many of x
2
, x
3
, . . . as possible. If this
interval covers x
1
, . . . , x
k
, then remove them and start again at x
k+1
.
Sort points so that x
1
x
2
x
n
Repeat until all points are covered:
Let x
j
be the first uncovered point
Pick the interval that covers x
j
and as many as possible of x
j+1
, x
j+2
, . . .
To argue that this scheme is correct, suppose the algorithm chooses intervals
C = [s
(1)
, e
(1)
], [s
(2)
, e
(2)
], . . . , where s
(1)
s
(2)
.
And let an optimal solution be
C

= [s

(1)
, e

(1)
], [s

(2)
, e

(2)
], . . . , where s

(1)
s

(2)
.
Claim. Substituting [s

(1)
, e

(1)
] [s
(1)
, e
(1)
] in C

also yields a valid solution.


Proof. [s

(1)
, e

(1)
] must contain x
1
. Since our algorithm starts by explicitly choosing the interval with
x
1
and the most other points, it follows that any x
i
in [s

(1)
, e

(1)
] is also in [s
(1)
, e
(1)
].
This means that the rst interval chosen by the algorithm is part of an optimal solution. Once it
removes the covered points, it gets a smaller version of the original problem, and can recurse.
3. Problem 6.1. Maximum-sum contiguous subsequence.
Subproblem: Let S(j) be the sum of the maximum-sum contiguous subsequence which ends exactly at
a
j
(but is possibly of length zero). We want max
j
S(j).
Recursive formulation: The subsequence dening S(j) either (i) has length zero, or (ii) consists of the
best subsequence ending at a
j1
, followed by element a
j
. Therefore,
S(j) = max{0, a
j
+S(j 1)}.
For consistency S(0) = 0.
Algorithm:
S[0] = 0
for j = 1 to n:
S[j] = max(0, a
j
+S[j 1])
return max
j
S[j]
Running time: Single loop: O(n).
1
4. (a) Problem 6.3. Yuckdonalds.
Subproblem: Let P(j) be the maximum prot achievable using only the rst j locations. We want
P(n).
Recursive formulation: In guring out P(j), we have two choices: either place a restaurant at
location j or dont. In the former case, we must skip all locations less than k miles to the left of
location j. To help with this, dene prev[j] to be the largest index i with m
i
m
j
k, or 0 if
there is no such index. Then,
P(j) = max(p
j
+P(prev[j]), P(j 1)).
For consistency, well set P(0) = 0.
Algorithm:
(First compute the prev[] array)
i = 0
for j = 1 to n:
while m
i+1
m
j
k:
i = i + 1
prev[j] = i
(Now the dynamic programming begins)
P[0] = 0
for j = 1 to n:
P[j] = max(p
j
+P[prev[j]], P[j 1])
return P[n]
Running time: O(n).
(b) The greedy strategy doesnt work. Consider a case where k = 10 and the locations are m
1
=
10, m
2
= 20, m
3
= 25, m
4
= 30, m
5
= 40, with prots p
1
= 100, p
2
= 100, p
3
= 101, p
4
= 100, p
5
=
100. The greedy scheme chooses locations 1, 3, 5, with prot 301, but the best solution is 1, 2, 4, 5,
with prot 400.
5. String reconstruction, revisited.
(a) Here is the logic:
There is a path from 1 to n in graph G
There are 1 = i
1
< i
2
< < i
k
= n + 1 such that all (i
j
, i
j+1
) E
There are 1 = i
1
< i
2
< < i
k
= n + 1 such that all x[i
j
i
j+1
1] are valid words
x[] is a valid sequence of words
Creating the graph involves testing O(n
2
) strings x[i j] to see if they are valid words; thereafter,
all that is needed is a call to explore. Therefore the total running time is O(n
2
).
(b) Create the same graph as in (a), and use BFS to nd the path from 1 to n + 1 that has the
minimum number of edges. The running time is still O(n
2
).
Heres the code:
Create graph G and let (dist[], prev[]) = BFS(G, 1)
S = (empty stack)
j = n + 1
while j > 1:
push(S, x[prev[j] j 1])
j = prev[j]
while S is not empty:
print pop(S)
2
6. Problem 6.7. Palindromes.
Subproblem: Dene T(i, j) to be the length of the longest palindromic subsequence of x[i . . . j]. We
want T(1, n).
Recursive formulation: In computing T(i, j), the rst question is whether x[i] = x[j]. If so, we can
match them up and then recurse inwards, to T(i +1, j 1). If not, then at least one of them is not in
the palindrome.
T(i, j) =

1 if i = j
2 +T(i + 1, j 1) if i < j and x[i] = x[j]
max{T(i + 1, j), T(i, j 1)} otherwise
For consistency set T(i, i 1) = 0 for all i.
Algorithm: Compute the T(i, j) in order of increasing interval length |j i|.
for i = 2 to n + 1:
T[i, i 1] = 0
for i = 1 to n:
T[i, i] = 1
for d = 1 to n 1: (interval length)
for i = 1 to n d:
j = i +d
if x[i] = x[j]:
T[i, j] = 2 +T[i + 1, j 1]
else:
T[i, j] = max{T[i + 1, j], T[i, j 1]}
return T[1, n]
Running time: There are O(n
2
) subproblems and each takes O(1) time to compute, so the total running
time is O(n
2
).
7. Problem 6.17. The change-making problem.
Subproblem: For any integer 0 u v, dene T(u) to be true if it is possible to make change for u
using the given coins x
1
, x
2
, . . . , x
n
. The answer we want is T(v).
Recursive formulation: Notice that
T(u) is true if and only if T(u x
i
) is true for some i.
For consistency, set T(0) to true.
Algorithm:
T[0] = true
for u = 1 to v:
T[u] = false
for i = 1 to n:
if u x
i
and T[u x
i
]: T[u] = true
Running time: The table has size v and each entry takes O(n) time to ll; therefore the total running
time is O(nv).
8. Problem 6.21. Vertex cover on trees.
Subproblem: Root the tree at any node r. For each u V , dene
T(u) = size of smallest vertex cover of the subtree rooted at u.
3
We want T(r).
Recursive formulation: In guring out T(u), the most immediate question is whether u is in the vertex
cover. If not, then its children must be in the vertex cover. Let C(u) be the set of us children, and
let G(u) be its grandchildren. Then
T(u) = min

1 +

wC(u)
T(w)
|C(u)| +

zG(u)
T(z)
where |C(u)| is the number of children of node u. The rst case includes u in the vertex cover; the
second case does not.
Algorithm:
Pick any root node r
dist[] = BFS(tree, r)
for all nodes u, in order of decreasing dist:
S
1
= 1 (option 1: include u in the vertex cover)
for all (u, w) E such that dist[w] = dist[u] + 1: (ie. w = child of u):
S
1
= S
1
+T[w]
S
2
= 0 (option 2: dont include u in the vertex cover)
for all (u, w) E such that dist[w] = dist[u] + 1: (ie. w = child of u):
S
2
= S
2
+ 1
for all (w, z) E such that dist[z] = dist[w] + 1: (ie. z = grandchild of u):
S
2
= S
2
+T[z]
T[u] = min{S
1
, S
2
}
return T[r]
Running time: The work done at each node is proportional to its number of grandchildren, |G(u)|.
Since

u
|G(u)| |V | (each node has at most one grandparent), the overall work done is linear.
9. Problem 6.22. Subset sum.
Subproblem: For j n and s t, let T(j, s) be true if some subset of {a
1
, a
2
, . . . , a
j
} adds up to s.
Recursive formulation:
In computing T(j, s), there is one choice: either leave out a
j
, or include it (in which case the remaining
elements must sum up to s a
j
):
T(j, s) = T(j 1, s) T(j 1, s a
j
),
where we consider the second option only if s a
j
. For consistency, T(j, 0) is always true and T(0, s)
is false for all s > 0.
Algorithm:
for j = 0 to n: T[j, 0] = true
for s = 1 to t: T[0, s] = false
for j = 1 to n:
for s = 1 to t:
T[j, s] = T[j 1, s]
if s a
j
: T[j, s] = T[j, s] T[j 1, s a
j
]
return T[n, t]
Running time: Two loops, O(nt).
4

Vous aimerez peut-être aussi