All Euler problems
Project Euler

Special Subset Sums: Testing

Let S(A) denote the sum of elements in set A of size n. We shall call it a special sum set if for any two non-empty, disjoint subsets B and C, the following properties hold: 1. S(B)!= S(C); that is...

Source sync Apr 19, 2026
Problem #0105
Level Level 05
Solved By 9,400
Languages C++, Python
Answer 73702
Length 436 words
linear_algebrabrute_forceoptimization

Problem Statement

This archive keeps the full statement, math, and original media on the page.

Let \(S(A)\) represent the sum of elements in set \(A\) of size \(n\). We shall call it a special sum set if for any two non-empty disjoint subsets, \(B\) and \(C\), the following properties are true:

1.
\(S(B) \ne S(C)\); that is, sums of subsets cannot be equal.
2.
If \(B\) contains more elements than \(C\) then \(S(B) \gt S(C)\).

For example, \(\{81, 88, 75, 42, 87, 84, 86, 65\}\) is not a special sum set because \(65 + 87 + 88 = 75 + 81 + 84\), whereas \(\{157, 150, 164, 119, 79, 159, 161, 139, 158\}\) satisfies both rules for all possible subset pair combinations and \(S(A) = 1286\).

Using sets.txt (right click and "Save Link/Target As..."), a 4K text file with one-hundred sets containing seven to twelve elements (the two examples given above are the first two sets in the file), identify all the special sum sets, \(A_1, A_2, \dots , A_k\), and find the value of \(S(A_1) + S(A_2) + \cdots + S(A_k)\).

Note: This problem is related to Problem 103 and Problem 106.

Problem 105: Special Subset Sums: Testing

Mathematical Foundation

Theorem 1. (Equivalent Condition for Property 2) For a sorted set A={a1<a2<<an}A = \{a_1 < a_2 < \cdots < a_n\}, Property 2 holds if and only if for all k=1,2,,n/2k = 1, 2, \ldots, \lfloor n/2 \rfloor:

i=1k+1ai>i=nk+1nai\sum_{i=1}^{k+1} a_i > \sum_{i=n-k+1}^{n} a_i

Proof. (\Rightarrow): Setting B={a1,,ak+1}B = \{a_1, \ldots, a_{k+1}\} and C={ank+1,,an}C = \{a_{n-k+1}, \ldots, a_n\} in Property 2 gives the inequality directly, since B=k+1>k=C|B| = k+1 > k = |C| and BC=B \cap C = \emptyset (because k+1nk+1k+1 \leq n-k+1 when kn/2k \leq \lfloor n/2 \rfloor).

(\Leftarrow): Let B,CB, C be disjoint subsets with B=m>=C|B| = m > \ell = |C|. Write B={b1<<bm}B = \{b_1 < \cdots < b_m\} and C={c1<<c}C = \{c_1 < \cdots < c_\ell\}. Since biaib_i \geq a_i (the ii-th element of BB is at least the ii-th smallest in AA) and cjan+jc_j \leq a_{n-\ell+j} (the jj-th element of CC is at most the (n+j)(n-\ell+j)-th smallest in AA), we have:

S(B)i=1maii=1+1ai>i=n+1naiS(C)S(B) \geq \sum_{i=1}^{m} a_i \geq \sum_{i=1}^{\ell+1} a_i > \sum_{i=n-\ell+1}^{n} a_i \geq S(C)

where the strict inequality uses the hypothesis with k=k = \ell (valid since <mn\ell < m \leq n implies n/2\ell \leq \lfloor n/2 \rfloor when BB and CC are disjoint subsets of an nn-element set). \square

Theorem 2. (Subset Sum Uniqueness Implies Property 1) Property 1 (no two non-empty disjoint subsets have equal sums) holds if and only if all 2n12^n - 1 non-empty subset sums are pairwise distinct.

Proof. (\Leftarrow): Trivial, since disjoint subsets are in particular distinct subsets.

(\Rightarrow): Suppose for contradiction that two distinct non-empty subsets B,CB', C' satisfy S(B)=S(C)S(B') = S(C'). Let D=BCD = B' \cap C', B=BDB = B' \setminus D, C=CDC = C' \setminus D. Then BC=B \cap C = \emptyset and BCB \cup C \neq \emptyset (since BCB' \neq C'). Moreover S(B)=S(B)S(D)=S(C)S(D)=S(C)S(B) = S(B') - S(D) = S(C') - S(D) = S(C).

If B=B = \emptyset, then C=DCC' = D \cup C and B=DB' = D, so S(DC)=S(D)S(D \cup C) = S(D), giving S(C)=0S(C) = 0. Since all elements are positive, this forces C=C = \emptyset, contradicting BCB \cup C \neq \emptyset. Similarly CC \neq \emptyset. Thus B,CB, C are non-empty, disjoint, with S(B)=S(C)S(B) = S(C), violating Property 1. \square

Lemma 1. (Complexity Bound for Subset Enumeration) For a set of nn elements, the number of non-empty subsets is 2n12^n - 1. Checking distinctness of all subset sums can be done in O(2n)O(2^n) expected time using a hash set.

Proof. There are 2n12^n - 1 non-empty subsets. We compute each subset sum incrementally (e.g., using Gray code enumeration, changing one element at a time, giving O(1)O(1) per subset sum update). Inserting into and querying a hash set takes O(1)O(1) expected time per operation. Total: O(2n)O(2^n). \square

Editorial

From a file of 100 sets, find those that are special sum sets and compute the sum of their S(A) values. A special sum set satisfies: 1. All subset sums are distinct. 2. Larger subsets have larger sums (size-ordering property). Approach: For each set, check Condition 2 in O(n), then Condition 1 in O(2^n). We iterate over each set A in sets.

Pseudocode

for each set A in sets
if s in seen

Complexity Analysis

  • Time: O(K2n)O(K \cdot 2^n) where K=100K = 100 is the number of sets and n12n \leq 12 is the maximum set size. The Property 2 check is O(n)O(n) per set and serves as a fast filter. The Property 1 check is O(2n)O(2^n) per set. In the worst case: 100212=409,600100 \cdot 2^{12} = 409{,}600 operations.
  • Space: O(2n)O(2^n) for the hash set storing subset sums during Property 1 verification.

Answer

73702\boxed{73702}

Code

Each problem page includes the exact C++ and Python source files from the local archive.

C++ project_euler/problem_105/solution.cpp
#include <bits/stdc++.h>
using namespace std;

/*
 * Problem 105: Special Subset Sums: Testing
 *
 * For each of 100 sets (sizes 7-12), check:
 *   Condition 2: min-sum of (k+1)-subset > max-sum of k-subset
 *   Condition 1: all 2^n - 1 nonempty subset sums are distinct
 *
 * Sum S(A) for all passing sets.
 * Complexity: O(100 * 2^12) = O(409600).
 */

bool isSpecialSumSet(vector<int>& a) {
    int n = a.size();
    sort(a.begin(), a.end());

    // Condition 2: for k = 1..n/2, sum of first k+1 > sum of last k
    for (int k = 1; k <= n / 2; k++) {
        int sumLow = 0, sumHigh = 0;
        for (int i = 0; i <= k; i++) sumLow += a[i];
        for (int i = 0; i < k; i++) sumHigh += a[n - 1 - i];
        if (sumLow <= sumHigh) return false;
    }

    // Condition 1: all subset sums must be distinct
    set<int> sums;
    for (int mask = 1; mask < (1 << n); mask++) {
        int s = 0;
        for (int i = 0; i < n; i++) {
            if (mask & (1 << i)) s += a[i];
        }
        if (sums.count(s)) return false;
        sums.insert(s);
    }
    return true;
}

int main() {
    // Try to read from file, fall back to stdin
    ifstream fin("p105_sets.txt");
    istream& in = fin.is_open() ? fin : cin;

    int total = 0;
    int specialCount = 0;
    string line;

    while (getline(in, line)) {
        if (line.empty()) continue;
        // Remove carriage return if present
        if (!line.empty() && line.back() == '\r') line.pop_back();
        replace(line.begin(), line.end(), ',', ' ');
        istringstream iss(line);
        vector<int> a;
        int x;
        while (iss >> x) a.push_back(x);
        if (a.empty()) continue;

        if (isSpecialSumSet(a)) {
            int s = 0;
            for (int v : a) s += v;
            total += s;
            specialCount++;
        }
    }

    assert(total == 73702);
    cout << total << endl;
    return 0;
}