Making Change (Unlimited Coins)
Given an unlimited supply of coins of denominations x[1], x[2], …, x[n], we wish to make change for a value v; that is, we wish to find a set of coins whose total value is v. This might not be possible: for instance, if the denominations are 5 and 10 then we can make change for 15 but not for 12. Give an O(nv) dynamic-programming algorithm for the following problem.
"Unlimited supply" ⇒ Knapsack with repetition. The key structural difference: when you take coin i, you may take it again, so you stay on row i, not i−1.
Either don't use denomination i at all (T(i−1,b)), or use one coin of it and keep denomination i available for the remainder (T(i, b−x[i]) — note the i, not i−1).
1 What one table entry actually asks
T(i, b) is a yes/no question:
Two knobs. i = how many coin types are on the table right now. b = the amount you're currently trying to hit. Every cell of the table holds one Boolean, true or false.
2 The two base cases (where it bottoms out)
T(i, 0) = true— the target 0 is always makeable: use no coins at all. The empty pile sums to 0. True for every i.T(0, b) = falsefor b ≥ 1 — with zero coin types available, you can't make any positive amount.
3 The recurrence is one decision: use coin type i, or don't
Standing at T(i, b), ask a single question about the newest coin type, x[i]. There are exactly two ways the answer could be "yes," and you're happy if either works — that's why the two options are joined by OR.
Then you must make b using only the earlier types 1..i−1. That is exactly T(i−1, b). Notice i drops to i−1 — you've put that coin away for good.
Lay down one x[i] coin. You've covered x[i] of the amount, so you still need to make b − x[i]. Crucially, coin type i is still available for that remainder — so the subproblem is T(i, b − x[i]), with i unchanged.
The guard if x[i] > b just kills Option B when the coin is bigger than the amount left — you can't place a coin worth more than the target — leaving only Option A.
4 The heart of it: why T(i, b−x[i]) and not T(i−1, b−x[i])?
This single index is the whole problem. It's the difference between "unlimited supply" and "each coin once."
Coin type i is still on the table for the rest of the amount → you may use it again → unlimited supply. This is what 6.17 asks for.
After using coin i once, it's gone → each coin used at most once. That's the 0/1 problem — a different question.
Concretely, with one coin type x = [3] and target 6, the "yes" path is: use coin 3 → need T(1, 3) → use coin 3 again → need T(1, 0) = true. It used coin type 1 twice, and it could only do that because the index stayed 1 both times. Had it dropped to T(0, 3) after the first use, that's false, and you'd wrongly conclude 6 is unmakeable.
5 The whole thing, filled out — x = [3, 5], v = 11
Bottom-up: fill row by row, and within each row go left to right (increasing b), because Option B reads T(i, b−x[i]) — a smaller b in the same row — which must already be filled.
A few cells traced so you can see both options firing:
T(i−1, b)), or spend one type-i coin and make the rest while still allowed to use type i (T(i, b−x[i])). That "still allowed" is the entire trick.With repetition: the "take" branch stays on the same item index — T(i, b−x[i]). Without repetition (0/1): the "take" branch moves to T(i−1, b−x[i]). Memorize this single-character difference; it's the most common re-skin on this exam.
Optional pseudocode not required by Ed #9
A mechanical translation of the 1-D with-repetition form.
function MakeChange(x[1..n], v): T[0] = true for b = 1 to v: T[b] = false for i = 1 to n: if x[i] <= b and T[b - x[i]]: T[b] = true; break return T[v]
Try it yourself
worked example + self-test1-D form: T(0)=true; T(b)=ORcoins c(c≤b AND T(b−c)). Answer T(v).
denominations x = [3, 5, 7] target v = 13
{3, 3, 7} (=13). Edge: x=[5,10], v=12 → false (only multiples of 5 reachable).denominations x = [4, 6, 9] target v = 17
Reveal answer
{4, 4, 9} (= 17).