Coins of different denominations are placed one after the other, pick coins to maximize the sum
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
This is the classic "maximum sum of non-adjacent elements" problem. The constraint that you cannot pick neighboring coins means greedy choices are unreliable, so the standard solution is dynamic programming: at each position, decide whether taking the current coin beats skipping it.
Problem Restatement
Given a row of coins, each with a value, choose a subset such that:
- no two chosen coins are adjacent
- the total sum is as large as possible
Example:
The optimal answer is 17, obtained by choosing 5, 10, and 2.
The crucial detail is that picking a coin blocks only its immediate neighbors, not every later coin.
Why Greedy Fails
A tempting strategy is "always take the larger coin you see." That fails because a locally good choice can block a better combination later.
For example:
Greedy might pick 5 and stop at total 5, but the optimal choice is 4 + 4 = 8.
That is why the problem needs a recurrence instead of a one-step rule.
Dynamic Programming Recurrence
Let dp[i] mean the best sum we can obtain using coins up to index i.
At each index i, there are only two meaningful options:
- skip coin
i, givingdp[i - 1] - take coin
i, givingcoins[i] + dp[i - 2]
So the recurrence is:
dp[i] = max(dp[i - 1], coins[i] + dp[i - 2])
Base cases:
- '
dp[0] = max(0, coins[0])if negative values are allowed' - '
dp[1] = max(dp[0], coins[1])'
If all values are non-negative, the logic is even simpler.
Python Implementation
This runs in linear time and always produces the optimal answer.
Space Optimization
The full dp array is not necessary if you only want the sum. Each state depends only on the previous two.
This version still runs in O(n) time but uses O(1) extra space.
Recovering Which Coins Were Chosen
Sometimes you need the actual set of selected coins, not just the best sum. In that case, keep the dp array and walk backward.
This makes the algorithm more useful in practice because you can explain or verify the chosen subset.
Variations
The same recurrence appears in many disguises:
- house robber problems
- selecting non-overlapping rewards on a line
- maximizing sum with spacing constraints
If the coins are arranged in a circle, the first and last coins become adjacent. Then solve the problem twice:
- once excluding the first coin
- once excluding the last coin
and take the better result.
Common Pitfalls
- Using a greedy strategy based on the biggest nearby coin, which misses better long-range combinations.
- Forgetting the correct recurrence and adding
coins[i]todp[i - 1], which illegally allows adjacent picks. - Handling the empty list and one-element list as afterthoughts instead of explicit base cases.
- Optimizing to constant space too early when you still need to reconstruct which coins were chosen.
- Missing the circular variant where the first and last coins are also adjacent and therefore cannot both be selected.
Summary
- This is a dynamic programming problem, not a greedy one.
- At each position, compare skipping the coin with taking it plus the best answer two steps back.
- The optimal recurrence is
dp[i] = max(dp[i - 1], coins[i] + dp[i - 2]). - The maximum sum can be computed in linear time and constant extra space.
- If you need the chosen coins themselves, keep the DP states and backtrack.
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.