Number of distinct sums of subsets
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
The distinct subset-sum problem asks how many different totals can be formed by summing arbitrary subsets of a given set or list of numbers. It appears in combinatorics and dynamic programming, and it is a good example of a problem where the number of subsets can be enormous even though the number of reachable sums may still be manageable.
Start With A Small Example
For the values [1, 2, 3], the subset sums are:
The distinct totals are:
There are 8 subsets but only 7 distinct sums because both {3} and {1, 2} produce 3.
Incremental Dynamic Programming
The cleanest general approach is to build the set of reachable sums incrementally. Start with {0} for the empty subset. When you process a value x, every currently reachable sum s creates a new reachable sum s + x.
That leads to a compact Python solution:
This is dynamic programming because it reuses previously computed reachable sums instead of enumerating every subset explicitly. It is simple, correct, and usually the best starting point.
Boolean DP When Values Are Nonnegative
If all values are nonnegative and the total sum is not too large, a boolean table is often faster and more memory-predictable:
The reverse iteration is crucial. If you loop forward, a value can be reused more than once during the same step, which turns the algorithm into something closer to an unbounded knapsack.
Bitset Optimization
A compact optimization for nonnegative integers is to treat reachability as bits in an integer:
Shifting left by x means "add x to every currently reachable sum." The bitwise OR merges old sums and new sums. This trick is elegant and often very fast in languages with efficient bit operations.
The Answer Is Not Determined By 2^n
It is easy to assume the answer is either close to 2^n or close to the total sum, but neither is reliable. A few examples show why:
- '
[1, 1, 1]gives sums0, 1, 2, 3, so the answer is4' - '
[2, 4]gives sums0, 2, 4, 6, so the answer is4' - '
[1, 3]gives sums0, 1, 3, 4, so the answer is also4'
Different value patterns can collapse many subsets onto the same total. That is why the distinct-sum count depends on the structure of the input, not just its size.
Generating-Function View
Mathematically, you can also write the problem as the polynomial:
The exponent s appears with a nonzero coefficient if and only if some subset sums to s. That viewpoint is elegant and useful in proofs, though for actual implementation the set-based and bitset dynamic programs are usually more practical.
What About Negative Numbers
Negative values make the problem slightly less convenient because the simple boolean-array approach assumes sums start at 0 and move upward. The set-based method still works:
That flexibility is one reason the set-based approach is a good default unless you know the input is nonnegative and performance matters enough to justify a specialized representation.
Common Pitfalls
- Enumerating all
2^nsubsets directly when dynamic programming would be far more efficient. - Forgetting that distinct subsets can produce the same total.
- Updating a boolean DP array forward and accidentally reusing the same item multiple times.
- Using bitset or array-based tricks without confirming the input is nonnegative.
- Assuming the number of distinct sums is determined only by
ninstead of by the input values.
Summary
- Distinct subset sums count unique reachable totals, not subsets.
- A set-based incremental DP is the simplest general-purpose solution.
- A boolean DP array is efficient when values are nonnegative and the total sum is moderate.
- A bitset implementation is a compact optimization for nonnegative integers.
- Input structure matters: many different subsets can collapse to the same sum.

