Home
DSA Patterns
Dynamic Programming
Coin Change
Coin Change
Find the fewest coins that make up an amount, or -1 if it cannot be made, with a bottom-up DP over amounts.
Problem Understanding
Coin Change: given coin denominations coins and a target amount, return the fewest coins that add up to amount, using each denomination as many times as you like. If no combination works, return -1.
Examples: coins = [1, 2, 5], amount = 11 returns 3 (5 + 5 + 1). coins = [2], amount = 3 returns -1.
Attempt 1: Greedy, Then Brute Force
Taking the largest coin that fits looks right for [1, 2, 5], but it fails in general: for [1, 3, 4] and amount 6, greedy picks 4 + 1 + 1 (three coins) while 3 + 3 uses two. Trying every combination recursively is correct but exponential — and it recomputes the same remaining amounts again and again, which is exactly what a DP table removes.
The Intuition: Which Coin Was Last?
Any way of making amount a ends with some last coin c. Before it, you had to make a - c — as cheaply as possible. So:
dp[a] = min(dp[a - c] + 1) over every coin c ≤ a.
dp[0] = 0; every other amount starts at ∞ (not reachable yet).- Fill
dp[1],dp[2], …dp[amount]in order, sodp[a - c]is always already known. - Return
dp[amount], or-1if it is still ∞.
Trying every coin as the last one is what makes this correct where greedy is not.
Interactive Walkthrough
coins [1, 2, 5], amount 11 · dp[a] = FEWEST COINS FOR a
BASE CASE
dp
0
1
2
3
4
5
6
7
8
9
10
11
Amount
—
Last coin
—
Answer
—
dp[0] = 0: zero coins make amount 0. Every other amount starts at ∞ (not yet reachable)
Next
Amount 1, last coin 1: dp[0] + 1 = 1 — better. dp[1] = 1
Coins
Target
The dp table runs left to right. For each amount, every coin is tried in turn, and the cell it reads — dp[a − coin] — is marked; when that gives fewer coins, the new count is written. The last step traces the answer's coins back through the table.
