The coin change problem sounds like something you'd tackle at a market stall, but in computer science it's one of the most cited puzzles in dynamic programming. It's the kind of brain teaser that hides in plain sight across crypto exchanges, AI optimizers, and even the routing logic that decides how your Bitcoin actually moves across a network. Once you see it, you can't unsee it.
Whether you're a developer building a DEX aggregator, a quant tuning a trading bot, or a curious student of algorithms, understanding how the coin change problem is solved is a genuine superpower in 2025. Let's break it down.
What Exactly Is the Coin Change Problem?
At its core, the coin change problem asks a deceptively simple question: given a set of coin denominations and a target amount, what's the minimum number of coins needed to make that amount? You can also flip it — count how many ways you can make change, or list every possible combination. The variant you tackle determines the strategy.
For example, if your denominations are 1, 5, 10, and 25, and you want to make 41 cents, the greedy approach grabs a quarter, a dime, a nickel, and a penny — four coins. That works because US currency is "canonical," meaning greedy always produces the optimal result. Try the same logic with a weird denomination set like 1, 3, and 4, and you'll fail spectacularly.
That's the twist: simple heuristics don't always win. The coin change problem is a favorite interview question because it exposes whether a candidate reaches for a brute-force recursion or a smarter dynamic programming solution.
The Two Main Variants
- Minimum coins variant: find the fewest coins to hit the target.
- Count combinations variant: count every distinct way to make the target (order doesn't matter).
- All combinations variant: list every valid set, useful for testing and validation.
How Dynamic Programming Solves Coin Change
Dynamic programming (DP) is the workhorse here. Instead of re-calculating subproblems from scratch, you store results in a table and reuse them. The two classic implementations are:
- Top-down with memoization: recursive calls cache intermediate results to avoid redundant work.
- Bottom-up with tabulation: iteratively fill a table of size (target + 1), where each cell represents the best answer for that sub-amount.
The bottom-up version is usually faster in practice because it eliminates recursion overhead. Time complexity lands at O(n × m) where n is the target amount and m is the number of denominations. For small targets that's nothing. For massive numbers — say, satoshi-level splits on a Bitcoin transaction — it can become a real concern.
This is where the problem stops being academic. When you're routing a swap across a DEX, every "coin" might be a liquidity pool, and every "amount" could be a user's trade size. The same DP table that works on a whiteboard has to execute in milliseconds under load.
When Greedy Fails (and Why It Matters)
Greedy algorithms pick the largest denomination that fits at each step. They're fast — O(n log m) after sorting — but only optimal for canonical coin systems. The 1, 3, 4 system is the classic counterexample: making 6 with greedy gives 4+1+1 (three coins), while the optimal answer is 3+3 (two coins). Add in transaction fees, slippage, or weird token decimals in a DEX, and you've basically reinvented this trap on-chain.
Why Coin Change Matters in Crypto and AI
Here's the part most tutorials skip. The coin change problem isn't just a textbook exercise — it's the silent backbone of several real systems that move real money.
DEX routing and swap optimization. Aggregators like major DEX routers treat your trade as a graph problem that shares DNA with multi-dimensional coin change. The "denominations" are token pairs, the "amount" is your input, and the goal is to minimize output cost (or maximize output). It's not a literal DP implementation, but the conceptual framing is identical.
Smart contract gas optimization. Solidity developers care about minimizing on-chain operations. Choosing the right way to break down a payment into discrete contract calls looks eerily like the coin change problem when you factor in gas costs as weights.
AI and combinatorial optimization. Modern AI systems — from reinforcement learning agents to neural combinatorial solvers — tackle variations of coin change daily. Think of a logistics bot deciding how to pack a delivery truck, or a recommendation engine selecting the smallest set of items that hits a target score. These are generalized coin change problems with extra constraints.
A Quick Pseudocode Sketch
Here's the bottom-up DP solution in plain language, in case you want to port it:
Initialize dp[0] = 0 and dp[i] = infinity for all i > 0. For each coin, iterate from coin value to target, updating dp[amount] = min(dp[amount], dp[amount - coin] + 1). The answer sits in dp[target].
Six lines. Decades of CS history. And the same logic quietly powers routing decisions across DeFi.
Common Pitfalls and Pro Tips
Even experienced developers slip on coin change. Watch for these traps:
- Integer overflow: large targets in Solidity or other typed languages can blow up. Use safe math libraries.
- Off-by-one errors: tables are usually sized target + 1; forget the +1 and you'll lose access to dp[target].
- Counting unordered vs. ordered combinations: the classic "ways to make change" problem assumes order doesn't matter. Flip the loop direction and you'll silently start counting permutations instead.
- Ignoring negative cases: if no combination sums to the target, your DP should return -1 or infinity, not crash.
If you're optimizing for production, profile the bottleneck first. A Python DP for a million-row target can take seconds; a C++ or Rust port drops it to milliseconds. The algorithm is the same — only the language changes the budget.
Key Takeaways
The coin change problem is a tiny puzzle with oversized influence. It teaches the value of dynamic programming, exposes when greedy heuristics break, and shows up everywhere from DEX aggregators to AI planners. Mastering it sharpens how you think about optimization in general — not just for currency.
Next time you see a swap router on a DEX, remember: somewhere under the hood, a developer wrestled with the same trade-offs you'll face writing your first DP table. The whiteboard-to-mainnet pipeline is shorter than you'd think.
Zyra