Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
100% found this document useful (1 vote)
634 views

Dynamic Programming Exercises Solution

This document discusses solutions to several dynamic programming problems: 1) Solving the 0-1 knapsack problem and fractional knapsack problem for a given set of items. 2) Extending the solution to another set of items with a different maximum weight. 3) Developing an algorithm to find the minimum number of stamps (of different denominations) needed to make change for any amount. 4) Computing the number of ways to make change for any amount using US coins. For each problem, the document provides the dynamic programming approach, tables or arrays used to store intermediate results, and analysis of the runtime.

Uploaded by

solomon
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
634 views

Dynamic Programming Exercises Solution

This document discusses solutions to several dynamic programming problems: 1) Solving the 0-1 knapsack problem and fractional knapsack problem for a given set of items. 2) Extending the solution to another set of items with a different maximum weight. 3) Developing an algorithm to find the minimum number of stamps (of different denominations) needed to make change for any amount. 4) Computing the number of ways to make change for any amount using US coins. For each problem, the document provides the dynamic programming approach, tables or arrays used to store intermediate results, and analysis of the runtime.

Uploaded by

solomon
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 12

Dynamic Programming (Solutions)

1. (a) Solve the following instance of the {0, 1} Knapsack Problem with
four items where the maximum allowed weight is Wmax = 10.
i
1
2
3
4
bi 25 15 20 36
wi
7
2
3
6
Solution: We proceed with this solution as outlined in the notes.
We define B[k, w] to be the optimal solution that can be obtained
using only the first k items, with maximum allowed total weight of
w. Here k ranges from 1 to 4, while w ranges from 0 to 10. We also
define B[0, w] = 0 for all w.
Then, as we did in class, we have to fill in the table, one row at a time,
to find the optimal solution, using the recurrence type of equation
that can be found in the class notes. This table will end up having
these values:
0 1 2
3
4
5
6
7
8
9 10
1 0 0 0
0
0
0
0 25 25 25 25
2 0 0 15 15 15 15 15 25 25 40 40
3 0 0 15 20 20 35 35 35 35 40 45
4 0 0 15 20 20 35 36 36 51 56 56
So the maximum benefit obtainable is 56. Since this example is small,
we can easily figure out that we want to take items 3 and 4 to obtain
this benefit. Otherwise, as also mentioned in class, we can trace
back through the table to find this out.
(b) For comparison, what is the solution to the corresponding Fractional
Knapsack problem with the same value of Wmax (use the greedy
method we discussed for this Fractional version)?
Solution: Recall that we compute the value indices and take items
in order of the value indices to fill up the knapsack. So I have added
another line to the table below for the value indices.
i
1
2
3
4
bi 25 15 20 36
wi
7
2
3
6
vi 3 47 7 12 6 23
6
So we select items in the order 2,3,4,1.
Doing so will lead us to the Fractional Knapsack solution consisting of
items 2, 3, and 56 of item 4, for a total benefit of 15 + 20 + 65 (36) = 65.
2. Do the same as above (find solutions to both the {0, 1} and Fractional
Knapsack problems) for this collection of items, where Wmax = 11.
i
bi
wi

1
14
4

2
12
3

3
15
8

4
20
7

5
16
3

Heres the table you


1 2 3
4
1 0 0 0 14
2 0 0 12 14
3 0 0 12 14
4 0 0 12 14
5 0 0 16 16

would get
5
6
14 14
14 14
14 14
14 14
16 28

for
7
14
26
26
26
30

the {0, 1}
8
9
14 14
26 26
26 26
26 26
30 30

version of this problem:


10 11
14 14
26 26
26 27
32 34
42 42

From this table, you can see that the maximum benefit for the {0, 1}
Knapsack Problem for this set of items is 42. What is the set of items
that achieves this benefit? You can find that by tracing backwards through
the table. Since B[5, 11] > B[4, 11] we see that item 5 must be used in the
solution.
Then we want to compare B[4, 8] and B[3, 8]. Since they are the same, we
conclude that item 4 is not used in the best solution. Continuing in this
way, we can determine that the best solution uses items 5, 2, and 1.
For the Fractional case, we again compute the value indices.
i
bi
wi
vi

1
14
4
3 23

2
12
3
4

3
15
8
1 78

4
20
7
2 67

5
16
3
5 13

So we select items (greedily) in the order 5,2,1,4,3.


This will give us the greedy solution for the Fractional case consisting of
items 5,2,1 and 17 of item 4, for a total benefit of 42 + 71 (20) = 44 67 .
3. (This is one of the problems from the sheet I gave out on the first day of
class.) Consider a post office that sells stamps in three different denominations, 1p, 7p, and 10p. Design a dynamic programming algorithm that
will find the minimum number of stamps necessary for a postage value of
N pence. (Note that a greedy type of algorithm wont necessarily give you
the correct answer, and you should be able to find an example to show
that such a greedy algorithm doesnt work.)
What is the running time of your algorithm?
Solution: Here I give quite a detailed solution to this problem. Note that
I dont necessarily expect you to provide pseudo-code for your proposed
solution. Your description should be sufficiently detailed to to give some
argument as to why your solution is correct.
Let S[n] denote the minimum number of stamps needed to make postage
for n pence. We clearly then have
S[0]

S[1]

S[2]

S[3]

S[4]

S[5]

S[6]

S[7]

S[8]

S[9]

S[10]

1.

and

These cases above should be considered our base cases and we then work
from these to compute values of S[n] for higher values of n.
The main idea, then is to consider what happens if we use a stamp of a
particular value. For example, if we want postage of n pence, then we
can clearly get it by taking one stamp of 1p, and S[n 1] stamps (of
appropriate values) to make up the remaining postage of (n 1)p. Or if
we take a 7p stamp, then we need S[n 7] stamps (of the right values)
to make up the rest, and similarly if we take a 10p stamp. This idea is
essentially the heart of the dynamic programming algorithm that we use.
The pseudo-code is given below:
Stamps(n)
 We assume here that n 0.
 This procedure will determine the minimum number of stamps
of values 1p, 7p, and 10p to make up total postage of n pence.
 Base cases
1 Set up the array S starting as above (with the
values S[i] for i = 0, . . . , 10).
2 if n 10 then
3
return S[n]
4
else
5
for j 11 to n do
6
S[j] = 1 + min{S[j 1], S[j 7], S[j 10]}
7 return S[n]
As you can see, there is one for loop in the body of the pseudo-code,
and this dominates the running time of the algorithm. Thus, finding S[N ]
takes time which is in O(N ).
Now we can find S[n] easily as above, but knowing this doesnt tell us the
exact nature of the stamps we need. Right? It would be nice to know
that we can make 45p postage with six stamps, and that we need one 1p,
two 7p, and three 10p stamps to do so. (For some values of n there could
certainly be more than one way to do this. For example, we can get 63p
with nine 7p stamps, or with six 10p and three 1p stamps.)
Well, we can easily do this too with another array called, say, P . Then P [n]
will be a vector of length 3 that will tell us what stamps we need to make
postage for np. For example, we would have P [45] = (1, 2, 3), meaning
that we need one 1p, two 7p, and three 10p stamps. In general, if we have
P [n] = (a, b, c), then we take a 1p stamps, b 7p stamps, and c 10p stamps

to make np postage. So, for example P [7] = (0, 1, 0), P [10] = (0, 0, 1), and
P [25] = (1, 2, 1). (As I said earlier, P [n] isnt really uniquely defined, but
thats not important for us. We just want some way, using the minimum
number of stamps, to get n pence.)
The calculation for S[n] doesnt change. All we do is determine which
denomination of postage we use and add it to the appropriate value of
P [n 1], P [n 7], or P [n 10]. The modified pseudo-code is given below.
The addition of vectors in lines 9, 11, and 13 is done component-wise in
the usual way, e.g. (3, 4, 1) + (0, 1, 0) = (3, 5, 1). The running time is still
O(n).
Stamps(n)
 We assume here that n 0.
 This procedure will determine the minimum number of stamps of values
1p, 7p, and 10p to make up total postage of n pence. We also return
a vector, P [n] which will tell us how many of each stamp is necessary.
 Base cases
1 Set up the array S starting as above (with the
values S[i] for i = 0, . . . , 10).
2 Also set up an array P [i] for i = 0, . . . , 10. That is P [0] = (0, 0, 0),
P [1] = (1, 0, 0), P [2] = (2, 0, 0), . . . , P [7] = (0, 1, 0), etc.
3
4
5
6
7

8
9
10
11
12
13
14

if n 10 then
return S[n] and P [n]
else
for j 11 to n do
S[j] = 1 + min{S[j 1], S[j 7], S[j 10]}
 Now set P [j] based on the value of S[j].
In other words, which stamp did we use?
if S[j] == (1 + S[j 1]) then
P [j] P [j 1] + (1, 0, 0)
elseif S[j] == (1 + S[j 7]) then
P [j] P [j 7] + (0, 1, 0)
else
P [j] P [j 10] + (0, 0, 1)
return S[n] and P [n]

4. (This is also from the initial problem sheet that I gave to you.)
American coins come in five different values, namely 50-cent, 25-cent, 10cent, 5-cent, and 1-cent coins. Therefore, if we wanted change for 11 cents
(or 11), we can do this with one 10 coin and one 1 coin, or two 5 coins
and one 1, or one 5 and 6 1 coins, or with eleven 1 coins. So there
are four ways to give change for 11.
How many ways are there to make change for N ? (And how can you
compute this number efficiently?)
We consider the coins in order 1, 5, 10, 25, 50. We compute the number
of ways of making change, first using only 1 coins, then using both 1
4

and 5 coins, and so forth. Doing the computations in this order, were
using the previously computed information to save us some work (in the
form of repeated computations).
So if you want, we can consider defining a 2-dimensional array (table) of
the form A[i, n] for i = 1, . . . , 5 and n = 1 . . . , N . The index i = 3, for
example, tells us that were using the first three coins to make change (i.e.
the 1, 5, and 10 coins). Obviously the value n is the amount for which
were making change. We want to find A[5, N ].
First of all, we note that A[1, n] = 1 for all n N . Why? Theres only
one way to make change for nusing only pennies. How many ways are
there to make change using 1 and 5 coins? We can find this using the
following bit of pseudo-code.
1
2

for j 0 to N Do
A[2, j] = bj/5c + 1

Verify that this number is correct? (Hint: The +1 comes from the fact
that you can use no 5 coins.)
Then we can find the values of A[3, n] in this fashion
1
2
3
4
5

for j 0 to N Do
A[3, j] = A[2, j]
for k 10 to N by 10 Do
 (Increment counter by 10.)
if (j k >= 0) Then
A[3, j] = A[3, j] + A[2, j k]

Because this pseudo-code has two for loops in it, you can see that it
runs in time O(N 2 ). You should also verify that it correctly computes the
number of ways of giving change using 1, 5 and 10 coins.
Adding on 25 and 50 coins is similar to the above pseudo-code, we just
increment the counter in the second for loop by 25 or 50 as appropriate
(and use the appropriate index i in the values of A[i, n]).
Overall, this will let us compute the value of A[5, N ], the value we want,
in time O(N 2 ).
Tardos.)
5. (Adapted from Algorithm Design by Jon Kleinberg & Eva
The current class of students at Sandhurst has an annual picnic (ok, maybe
they dont really do this, but for the purposes of this question they do...).
This year it happens that the picnic has fallen on a rainy day and the
ranking officer decides to postpone the picnic and must notify everyone
by phone. Here is the mechanism for doing this.
Each person except for the ranking officer reports to a unique superior
officer. Thus, the reporting hierarchy can be described as a tree T , rooted
at the ranking officer, in which each other node v has a parent node u
equal to his or her superior officer. Conversely, we can call v a direct
subordinate of u. See the picture below, where A is the ranking officer, B
and D are direct subordinates of A, and C is a direct subordinate of B.
5

Am

J
J^


J
m
Bm
D

?
Cm
To notify everyone of the postponement, the ranking officer first calls each
of her direct subordinates, one at a time. As soon as each subordinate gets
the phone call, he or she must notify each of his or her direct subordinates,
one at a time. The process continues in this was until everyone is notified.
Note that each person in this process will only call direct subordinates,
for example A would not be allowed to call C.
We can picture this notification process as divided into rounds. In one
round, each person who has already learned of the postponement can call
one of his or her subordinates on the phone. The number of rounds it takes
for everyone to be notified might depend upon the sequence in which each
person calls their direct subordinates. In the given example, it will take
only two rounds if A starts by calling B, but will take three rounds if A
starts by calling D.
Give an efficient algorithm that determines the minimum number of rounds
needed for everyone to be notified for a rooted tree T as described above.
How can you output a sequence of phone calls (i.e. a schedule for each
person) that achieves this minimum number of rounds?
Solution: The recursive type of problems we need to consider naturally
come from looking at a node and all of the descendants of that node. In
the example above, B has one child, so needs one round to inform its
children. If B had three children, then it would need three rounds to
inform all of its children.
In general, a vertex wants to inform its children in a good order in
which to minimize the time needed to inform all of the descendants of
itself. Nodes just above leaves will need a number of rounds equal to their
children, but vertices with larger heights (closer to the root) will need
even more than the number of children, as you need to consider how long
is needed to inform the entire subtree rooted at a vertex. You need to
consider more complicated trees in your solution method. (Unfortunately,
the small tree that Ive drawn here might be slightly misleading.)
Let us use a label called r(v) for a vertex v. (Im using r as Im thinking
that the value tells me how many rounds are necessary until v and all of
its descendants have been informed of the news.)
A leaf has label r(v) = 0 (if that vertex knows the news, then you need
zero rounds until it (and all of its non-existent children) are informed of
the news). Nodes just above leaves will have a label
r(v) = number of children of v.
Now assume that we have (recursively) calculated values of r(w) for each
child of an internal vertex v, and we want to find r(v). (As above, we
6

know how to find r(v) for vertices with height 1, so we need to consider
vertices with height 2 and larger.)
How do we find r(v)? We want to inform the children of v in a proper
order so that we minimize the value of r(v). Intuitively (I hope), it seems
that we want to inform the child, w, of v having largest value of r(w), so
that w learns the message first, and then can begin to inform its children
as early as possible (while v continues to inform the remaining children,
keeping in mind that this process is parallel in the sense that each vertex
that knows the message can inform one of its children every round).
So, with this in mind, suppose that v has k children, which I will call
w1 , w2 , . . . , wk , and further suppose that I have labeled the children of v
so that
r(w1 ) r(w2 ) r(wk ).
(1)
(Note that we can have each child wi inform its parent of the value of
r(wi ) when it has completed computing this value, and then v can sort
the r(wi ) values once it knows them all.)
Then, v will inform its children in the order w1 , w2 , . . . , wk . So, child wi
will be informed on round i after v becomes informed of the message.
Then, the subtree rooted at vertex wi requires r(wi ) additional rounds
until all vertices in that subtree are informed.
Therefore, I claim that
r(v) = max {1 + r(w1 ), 2 + r(w2 ), 3 + r(w3 ), . . . , k + r(wk )} .

(2)

Will Equation (2) actually find the minimum possible value of r(v)?
To see that it does, we assume that the values of r(w1 ), . . . , r(wk ) have
been correctly computed (recursively). (This should be clear for leaves
and for vertices of height 1.) Also, assume that the children of v have
been labeled in a manner so that Equation (1) holds.
Then let i {1, . . . , k} be a value so that r(v) = i + r(wi ) holds (i.e. wi is
a child that defines the value of r(v)). What would happen if we were to
swap the value of r(wi ) with some other value r(wj ) for i 6= j? (In other
words, could I somehow lower the value of r(v) by rearranging the order
in which the children of v are informed?)
If we take j < i, then let us compare the two values i + r(wj ) and i + r(wi )
(since vertex wj is now being informed in round i, and r(wj ) rounds are
needed to inform all descendants of wj ). By the ordering of the r values
of the descendants of v (Equation (1)), we have
r(wj ) r(wi )

hence,

i + r(wj ) i + r(wi ).

Therefore, the value of r(v) wouldnt decrease through such a swap of the
vertices wi and wj .
Suppose, instead, that we swap vertices wi and wj for some j > i? Then,
let us consider the two values i + r(wi ) and j + r(wi ). (Now, vertex wi is
now being informed in round j, and r(wi ) rounds are required to inform
all the descendants of wi .)
7

Since j > i, we have


j + r(wi ) > i + r(wi ),
so now even more rounds are required to inform wi and all of that subtree,
increasing the value of r(v) if we were to swap the order of informing wi
and wj !
So swapping the order in which we inform vertices cannot help to reduce
the value of r(v) that we find in Equation (2). Thus, Equation (2) computes the correct value of r(v) for an internal vertex v (assuming that v
knows the r values of all of its children).
(Note: The argument I have done above is really a proof by induction,
although I havent explicitly use the word induction here.)
As for the schedule for informing the nodes, once all of the r(v) values
have been computed for all nodes, then assuming that a vertex knows the
r values for all its children, it simply informs them in decreasing r value
once vertex v receives the news.
Also note that the r values can be computed by basically performing a
depth-first search on the graph. Once all descendants of a node v have
been visited in the DFS (and each child of v has reported its r value
to v, then v sorts those r values, and computes the value of r(v) as in
Equation (2) and informs its parent).
A depth-first search on a graph with n vertices and m edges can be performed in time O(m). Since a tree has m = n1, and sorting a list of size k
can be done in time O(k log k). If = max number of children of any node,
then we can find all r values in time O(n log ), which is the time for a
DFS on the tree, together with sorting the (at most ) r values at each
vertex.
6. Consider the set of weighted intervals given below, where si is the start
time, fi is the finish time, and vi is the value of the interval.
j
1
2
3
4

sj
0
2
9
7

fj
6
10
15
18

vj
2
4
6
7

p(j)
0
0
1
1

Solve this instance of the weighted interval scheduling problem, i.e. find a
set of (non-conflicting) intervals with maximum total weight.
Solution: Note that the intervals are already sorted by their finish time,
and I have added the value p(j) for each interval. Recall that the value
p(j) is the largest index of an interval which is compatible with interval
j, i.e. interval p(j) could be scheduled together with interval j, but not
interval p(j)+1 as that would conflict with interval j. (Of course, p(j) = 0
if there is no such interval.)

Now recall that Opt(j) was defined to be the best solution that is obtainable using intervals 1, . . . , j, where we define Opt(0) = 0. Then we have
that
Opt(j) = max {Opt(j 1), vj + Opt(p(j))} .
Therefore, we have
Opt(0)

Opt(1)

max {Opt(0), v1 + Opt(p(1))} = 2

Opt(2)

max {Opt(1), v2 + Opt(p(2))} = max{2, 4 + 0} = 4

Opt(3)

max {Opt(2), v3 + Opt(p(3))} = max{4, 6 + 2} = 8

Opt(4)

max {Opt(3), v4 + Opt(p(4))} = max{8, 7 + 2} = 9

So there is a schedule that gives us a weight (or value) of 9. Its easy


enough to see, in this case, that we schedule intervals 1 and 4 to get this
value.
In general, if you want to reconstruct the actual schedule that will achieve
the maximum value, then you start with the value of Opt(n) (for n intervals) and determine if Opt(n) = Opt(n 1) or if Opt(n) = vn + Opt(p(n)).
In the first case, interval n isnt used and then we proceed to the value
Opt(n 1) and do the same to continue finding the schedule.
In the second case, interval n is scheduled, and then we proceed to examine
task p(n) (and the value of Opt(p(n))) to determine the next (i.e. previous)
interval to schedule.
7. Do the same as the previous problem for this collection of weighted intervals.
j
1
2
3
4
5
6
7
8

sj
1
2
3
5
7
12
9
15

fj
4
6
9
10
14
16
18
20

vj
4
2
1
6
3
1
5
3

p(j)
0
0
0
1
2
4
3
5

Solution: Again, I have added in the values of p(j) for each interval in
the table, as the tasks are already sorted by their finishing times.
In this case we have these values:
Opt(0)

Opt(1)

max {Opt(0), v1 + Opt(p(1))} = max{0, 4 + 0} = 4

Opt(2)

max {Opt(1), v2 + Opt(p(2))} = max{4, 2 + 0} = 4

Opt(3)

max {Opt(2), v3 + Opt(p(3))} = max{4, 1 + 0} = 4

Opt(4)

max {Opt(3), v4 + Opt(p(4))} = max{4, 6 + 4} = 10

Opt(5)

max {Opt(4), v5 + Opt(p(5))} = max{10, 3 + 4} = 10

Opt(6)

max {Opt(5), v6 + Opt(p(6))} = max{10, 1 + 10} = 11

Opt(7)

max {Opt(6), v7 + Opt(p(7))} = max{11, 5 + 4} = 11

Opt(8)

max {Opt(7), v8 + Opt(p(8))} = max{11, 3 + 10} = 13

So the maximum value obtainable is 13, which comes from scheduling


intervals 8, 4, and 1.
8. Suppose youre managing construction of billboards on the Rocky & Bullwinkle Memorial Highway, a heavily traveled stretch of road that runs
west-east for M miles. The possible sites for billboards are given by numbers x1 < x2 < < xn , each in the interval [0, M ], specifying their
position in miles measured from the western end of the road. If you place
a billboard at position xi , you receive a revenue of ri > 0.
Regulations imposed by the Highway Department require that no two
billboards be within five miles or less of each other. Youd like to place
billboards at a subset of the sites so as to maximize your total revenue,
subject to this restriction.
For example, suppose M = 20 and n = 5 with
{x1 , x2 , x3 , x4 , x5 } = {6, 7, 12, 13, 14}
and
{r1 , r2 , r3 , r4 , r5 } = {5, 6, 5, 3, 1}.
Then the best solution is to place billboards at x1 and x3 to achieve a
revenue of 10.
Describe a (dynamic programming) procedure to find a solution for this
problem. What is the running time of your procedure (this should be
polynomial in n)?
Hint: As a first step towards the solution, define (similar to the Weighted
Interval Scheduling Problem) e(j) to be the easternmost site that is more
than 5 miles away from xj . In other words, if you place a billboard at
xj , then x1 , x2 , . . . , xe(j) are also valid places to place billboards (subject
to the same restriction about distances). Note that computing the e(j)
values takes time O(n).
Solution: The hint contains much of the solution. With the e(j) defined
as above, we also define Opt(j) to be the best revenue obtainable using
sites {x1 , x2 , . . . , xj }. (Note that we define Opt(0) = 0, and e(j) = 0
should have an obvious meaning, namely there is no other location smaller
than xj that is compatible with xj , e.g. if x3 = 4, then by placing a
billboard at site x3 , we cannot use x1 or x2 as they would be within five
miles of x3 . In that case we can define e(3) = 0.)
Then, we see that Opt(1) = r1 and also
Opt(j) = max{rj + Opt(e(j)), Opt(j 1)}.

10

Why? If we use location xj , then we combine this with the best solution
from sites x1 , x2 , . . . , xe(j) . Otherwise if we dont use xj then we take the
best solution from sites x1 , x2 , . . . , xj1 . Since were trying to maximize
our revenue, we take the better (maximum) of those two options.
9. Longest Increasing Subsequence. (This is a classical dynamic programming problem.) Given a sequence of real numbers A1 , A2 , . . . , An , determine a subsequence (not necessarily contiguous) of maximum length in
which the values form a strictly increasing sequence.
For example, given the sequence of integers
3, 4, 14, 0, 1, 3, 5, 2, 5, 10
the subsequence consisting of 4, 5, 10 is an increasing subsequence, as is
3, 0, 3, 5, 10. Your task is to find a longest subsequence so that the values
are strictly increasing. (There might be repeated numbers in the original
sequence, but there can be no repeats in a longest subsequence since it
must be strictly increasing.)
Hint: Define L(j) to be the length of the longest increasing subsequence
that ends at (and includes) position j. How can you find L(j) in terms
of the values L(i) for i < j? Once you know the L(j) values, whats the
answer to the original problem? And how long does it take to compute
all of the L(j) values?
Solution: As suggested above, we define L(j) to be the length of longest
increasing subsequence that ends at (and includes) position j. If we are
able to compute these L(j) values, then the solution to our problem is
equal to L = max{L(1), L(2), . . . , L(n)}. Why? Because the longest
increasing subsequence must end at (and include) one of the positions
1, 2, . . . , n.
We note that L(1) = 1, since the single value A1 is an increasing subsequence. Also, L(2) = 1 or 2, depending upon whether A1 A2 or
A1 < A2 (recall that the sequence must be strictly increasing).
If we have computed L(1), L(2), . . . , L(i) for some i, how do we use these
values to find L(i + 1)? We compute
L(i+1) = 1+max{L(j) : Aj < Ai+1 }, or possibly L(i+1) = 1 (see below).
In other words, check all Aj , find those that are less than Ai+1 . We do this
because if Aj < Ai+1 , then we can increase the longest subsequence that
ends at Aj by one more value (namely, adding Ai+1 to that subsequence).
Note that if there are no values Aj that are less than Ai+1 , then we define
L(i + 1) = 1 (as for L(1)).
Computing L(i + 1) requires us to check all of the values A1 , . . . , Ai , i.e.
O(i) time. So, in total, computing all of the L(i) values takes O(1+2+3+
+n) = O(n2 ) time. Then finding the value L = max{L(1), L(2), . . . , L(n)}
takes O(n) time. So finding the value L takes O(n2 ) time.
10. Balanced Partition. Suppose that you have a set, A = {a1 , . . . , an }, of n
integers, each of which is between 0 and K (inclusive). Your goal is to find
11

a partition of A into two sets S1 and S2 (so S1 S2 = A and S1 S2 = )


that minimizes
|sum(S1 ) sum(S2 )|,
where sum(Si ) equals the sum of the values in the set Si .
Hint: Define V (i, j) = 1 if there is some subset of {a1 , . . . , ai } that sums
up to the value j (i.e. some collection from the first i integers sums up to
j), otherwise set V (i, j) = 0.
How many different values of V (i, j) do you need to compute (in terms
of n and K)? How can you compute the V (i, j) values if you know all of
the V (i 1, j) values? How can you use the collection of V (i, j) values to
answer the original question (and find the minimum value of |sum(S1 )
sum(S2 )|)?
Solution: Since there are n different numbers, each of which is at most
K, the sum of all of the n numbers is at most nK (i.e. j can range from
0 to nK for each value of i). Hence, there are at most O(n2 K) values
V (i, j) to compute. (This is effectively the running time to find a solution
to this Balanced Partition problem.)
For i = 1, we have V (1, a1 ) = 1 and V (1, j) = 0 for j 6= a1 .
For i 2, how can we find V (i, j) given that we have all of previously
computed values (i.e. all of the V (1, j), V (2, j), . . . , V (i 1, j) values for
all j)?
First of all, we have V (i, j) = 1 if V (i 1, j) = 1 or if V (i 1, j ai ) = 1.
(Why?) Otherwise, V (i, j) = 0.
So after computing all of the V (i, j) values, what do we do?
Pn
Let T = 21 i=1 ai . Then T is half of the sum of all the values in the set
A. If T is an integer, we can first check to see if V (n, T ) = 1. If this is the
case, then there is a partition S1 , S2 such that |sum(S1 ) sum(S2 )| = 0.
(Why?)
If T is not an integer, or if T is an integer but V (n, T ) = 0, then what do we
do? For each value j with V (n, j) = 1, this means that there are two sets
S1 , S2 such that sum(S1 ) = j and sum(S2 ) = 2T j. For those particular
sets, we have |sum(S1 ) sum(S2 )| = |j (2T j)| = |2j 2T | = |2T 2j|.
Were trying to minimize that value, so we compute
min{|2T 2j| : V (n, j) = 1 and j T }
to find this minimum value. (We need only consider the values j T in
the minimum because of the symmetry of the problem, i.e. there is a set S1
with sum(S1 ) = j if and only if there is a set S2 with sum(S2 ) = 2T j.
Furthermore, we would likely consider the values V (n, j) in decreasing
order of j starting from T (or the closest integer to T if it is a fraction)
since we want to minimize the difference.)
This last part of computing the minimum takes time O(T ) O(n2 K), so
overall the whole algorithm can run in time O(n2 K).

12

You might also like