Coin Change Problem

Algorithms

You've got a target amount and a list of coin denominations. Two related questions: what's the fewest coins that sum to , and how many distinct combinations of coins sum to ?

Dynamic programming approach

Keep one array, , of length . means different things depending on which version you're solving. For the fewest-coins question, is the minimum number of coins that sum to . For the number-of-ways question, is the count of distinct combinations that sum to . The algorithm is roughly the same in both cases. The only difference is the update rule for .

Time complexity

Each cell of fills in constant time by looking back at smaller cells. With coin denominations and target , the whole thing runs in .

Implementation

def coin_change_min_coins(coins, T):
    """Minimum number of coins that sum to T, or -1 if impossible."""
    dp = [float('inf')] * (T + 1)
    dp[0] = 0
    for x in range(1, T + 1):
        for coin in coins:
            if x >= coin:
                dp[x] = min(dp[x], dp[x - coin] + 1)
    return dp[T] if dp[T] != float('inf') else -1


def coin_change_num_ways(coins, T):
    """Count of distinct coin combinations that sum to T."""
    dp = [0] * (T + 1)
    dp[0] = 1
    for coin in coins:
        for x in range(coin, T + 1):
            dp[x] += dp[x - coin]
    return dp[T]


# Example: target 11 with coins {1, 2, 5}.
coins, T = [1, 2, 5], 11
print(coin_change_min_coins(coins, T))   # 3   (e.g., 5 + 5 + 1)
print(coin_change_num_ways(coins, T))    # 11

Exercises

A full exercise set is available for this topic, structured as one worked example + 7 practice problems (across 7 surface contexts) + 2 pattern-resistant check problems.

Open the Coin Change & Dynamic Programming exercise set → Recognize a problem as having overlapping sub-problems and optimal substructure; identify a state variable and a recurrence that combines smaller solutions into larger ones; tabulate from the base case upward in O(states × choices) time.