Lecture 9. Dynamic Programming:
optimal coin change
We have seen this problem before: you are given an
amount in cents, and you want to make change using a
system of denominations, using the smallest number of
coins possible. Sometimes the greedy algorithm gives
the optimal solution. But sometimes (as we have seen) it
does not

an example was the system (12, 5, 1), where
the greedy algorithm gives 15 = 12 + 1 + 1 + 1 but a
better answer is 15 = 5 + 5 + 5. And sometimes Greedy
cannot even find the proper changes: (25,10,4), change
for 41 cents.
So how can we find the optimal solution (fewest coins)
when the greedy algorithm may not work? One way is
using dynamic programming.
Optimal coin

changing

The idea: to make change for n cents, the optimal
method must use some denomination d
i
. That is, the
optimal is made by choosing the optimal solution for
n
–
d
i
for some d
i
, and adding one coin of d
i
to it. We
don't know which d
i
to use, but some must work. So
we try them all, assuming we know how to make
optimal changes for < n cents.
To formalize: letting opt[j] be the optimal number of
coins to make change for j cents, we have:
opt[j] = 1 + min( opt[j

d
i
]) over all d
i
≤j
Optimal coin

change:
coins(n, d[1..k])
/* returns optimal number of coins to make change for n using
denominations d[1..k], with d[1] = 1 */
for j := 1 to n do
opt[j] := infinity;
for i := k downto 1 do
if d[i] = j then
opt[j] := 1;
largest[j] := j;
else if d[i] < j then
a := 1+opt[j

d[i]];
if a < opt[j] then
opt[j] := a;
largest[j] := d[i];
return(opt[n])
Running time: O(
nk
)
Input size: ?
Example.
Suppose we use the
system of denominations
(1,5,18,25). To represent
29, the greedy algorithm
gives 25+1+1+1+1,
Our algorithm: largest
coin 18. 29

18=11, which
has a representation of
size 3, with largest coin 5.
11

5=6, which has a
representation of size 2,
with largest coin 5. 6

5=1.
So 29 = 18 + 5 + 5 + 1.
j opt[j] largest[j]
1 1 1
2 2 1
3 3 1
4 4 1
5 1 5
6 2 5
7 3 5
8 4 5
9 5 5
10 2 5
11 3 5
12 4 5
13 5 5
14 6 5
j opt[j] largest[j]
15 3 5
16 4 5
17 5 5
18 1 18
19 2 18
20 3 18
21 4 18
22 5 18
23 2 18
24 3 18
25 1 25
26 2 25
27 3 25
28 3 18
29 4 18
Paradigm #7. Exploiting the problems’ structure
Example: Computing GCD
We say d is a divisor of u if there
exists an integer k such that u =
kd. We write d  u. We say d is a
common divisor of u and v if d  u
and d  v. We say d is the greatest
common divisor if d is a common
divisor of u and v and no other
common divisor is larger.
Example: gcd(12,18)=6.
Observe:
d  u & d  v
iff
d  v and d  (u mod v)
Euclid’s Alg (300BC)
Euclid(u,v)
while (v ≠ 0) do
(u, v) := (v, u mod v)
return(u)
Thm (Finck 1841). This algorithm
runs in O(log v) steps, for u>v>0.
Proof: Let r = u mod v.
Case 1. v>u/2, then r =u

v < u/2
Case 2. v=u/2, then r=0
Case 3. v< u/2, then r<v<u/2
So after 2 steps, the numbers
decrease by factor of 2. Hence
after O(log v) steps, to 0.
Comments 0
Log in to post a comment