5
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.

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

Embed Size (px)

Citation preview

Page 1: 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

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.

Page 2: 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

Optimal coin-changing --

The idea: to make change for n cents, the optimal method must use some denomination di. That is, the optimal is made by choosing the optimal solution for n – di

for some di, and adding one coin of di to it. We don't know which di 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-di]) over all di≤j

Page 3: 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

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: ?

Page 4: 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

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

Page 5: 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

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.