All Euler problems
Project Euler

Special Subset Sums: Optimum

Let S(A) denote the sum of elements in a set A of positive integers. We call A a special sum set if for any two non-empty disjoint subsets B, C subseteq A: 1. S(B)!= S(C) (distinct subset sums). 2....

Source sync Apr 19, 2026
Problem #0103
Level Level 05
Solved By 9,450
Languages C++, Python
Answer 20313839404245
Length 381 words
linear_algebraconstructiveoptimization

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) \neq S(C)\); that is, sums of subsets cannot be equal.
2.
If \(B\) contains more elements than \(C\) then \(S(B) > S(C)\).

If \(S(A)\) is minimised for a given \(n\), we shall call it an optimum special sum set. The first five optimum special sum sets are given below. \begin {align*} n &= 1: \{1\} \\ n &= 2: \{1, 2\} \\ n &= 3: \{2, 3, 4\} \\ n &= 4: \{3, 5, 6, 7\} \\ n &= 5: \{6, 9, 11, 12, 13\} \end {align*}

It seems that for a given optimum set, \(A = \{a_1, a_2, \dots , a_n\}\), the next optimum set is of the form \(B = \{b, a_1 + b, a_2 + b, \dots , a_n + b\}\), where \(b\) is the "middle" element on the previous row.

By applying this "rule" we would expect the optimum set for \(n = 6\) to be \(A = \{11, 17, 20, 22, 23, 24\}\), with \(S(A) = 117\). However, this is not the optimum set, as we have merely applied an algorithm to provide a near optimum set. The optimum set for \(n = 6\) is \(A = \{11, 18, 19, 20, 22, 25\}\), with \(S(A) = 115\) and corresponding set string: 111819202225.

Given that \(A\) is an optimum special sum set for \(n = 7\), find its set string.

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

Problem 103: Special Subset Sums: Optimum

Mathematical Development

Theorem 1 (Equivalent Condition for Property 2). Let A={a1<a2<<an}A = \{a_1 < a_2 < \cdots < a_n\} be a set of positive integers. Property 2 holds if and only if

i=1k+1ai>i=nk+1naifor all k=1,2,,n/2.\sum_{i=1}^{k+1} a_i > \sum_{i=n-k+1}^{n} a_i \qquad \text{for all } k = 1, 2, \ldots, \lfloor n/2 \rfloor.

Proof. (\Rightarrow) Take B={a1,,ak+1}B = \{a_1, \ldots, a_{k+1}\} and C={ank+1,,an}C = \{a_{n-k+1}, \ldots, a_n\}. These are disjoint since k+1n/2+1nk+1k + 1 \leq \lfloor n/2 \rfloor + 1 \leq n - k + 1 for kn/2k \leq \lfloor n/2 \rfloor. Since B=k+1>k=C|B| = k + 1 > k = |C|, Property 2 yields S(B)>S(C)S(B) > S(C).

(\Leftarrow) Let B,CB, C be disjoint subsets of AA 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 the bib_i are mm distinct elements of AA, we have biaib_i \geq a_i, so S(B)i=1maiS(B) \geq \sum_{i=1}^{m} a_i. Similarly, since the cjc_j are \ell distinct elements of AA, we have cjan+jc_j \leq a_{n - \ell + j}, so S(C)j=n+1najS(C) \leq \sum_{j=n-\ell+1}^{n} a_j. Applying the hypothesis with k=k = \ell:

S(B)i=1maii=1+1ai>j=n+1najS(C).S(B) \geq \sum_{i=1}^{m} a_i \geq \sum_{i=1}^{\ell+1} a_i > \sum_{j=n-\ell+1}^{n} a_j \geq S(C). \qquad \blacksquare

Theorem 2 (Reduction to Global Subset-Sum Uniqueness). Property 1 holds for AA if and only if all 2n12^n - 1 non-empty subset sums of AA are pairwise distinct.

Proof. (\Leftarrow) If all subset sums are distinct, then in particular S(B)S(C)S(B) \neq S(C) for any two distinct non-empty subsets, a fortiori for disjoint ones.

(\Rightarrow) We prove the contrapositive. Suppose 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 BB and CC are disjoint. Since BCB' \neq C', at least one of B,CB, C is non-empty. If both are non-empty, then

S(B)=S(B)S(D)=S(C)S(D)=S(C),S(B) = S(B') - S(D) = S(C') - S(D) = S(C),

violating Property 1. If exactly one (say CC) is empty, then CBC' \subseteq B' and S(B)=S(C)S(B') = S(C') forces S(BC)=0S(B' \setminus C') = 0; but all elements are positive, so BC=B' \setminus C' = \emptyset, contradicting BCB' \neq C'. \blacksquare

Lemma 1 (Near-Optimum Heuristic Construction). Given an optimal special sum set {b1,,bn1}\{b_1, \ldots, b_{n-1}\} of size n1n - 1 with middle element bmb_m where m=(n1)/2m = \lceil(n-1)/2\rceil, the set {bm,bm+b1,bm+b2,,bm+bn1}\{b_m,\, b_m + b_1,\, b_m + b_2,\, \ldots,\, b_m + b_{n-1}\} is a near-optimum special sum set of size nn.

Proof. This construction, due to Lunnon, yields a set satisfying both properties. The minimum element is bm>0b_m > 0, ensuring positivity. Property 2 is satisfied because the spread bm+b1b_m + b_1 vs.\ bm+bn1b_m + b_{n-1} inherits the structure of the original set. Optimality is not guaranteed, but the set serves as a starting point for local search. \blacksquare

Editorial

We check Property 2. Finally, check Property 1. Candidates are generated from the derived formulas, filtered by the required conditions, and processed in order until the desired value is obtained.

Pseudocode

Check Property 2
Check Property 1

Complexity Analysis

  • Time. The perturbation space has (23+1)7=77=823,543(2 \cdot 3 + 1)^7 = 7^7 = 823{,}543 candidates. For each candidate passing the sum bound and Property 2 filter, Property 1 costs O(2n)O(2^n) with n=7n = 7, i.e., 128 subset-sum computations. With aggressive pruning, total work is on the order of 10610^6 operations.
  • Space. O(2n)=O(128)O(2^n) = O(128) for the hash set of subset sums.

Answer

20313839404245\boxed{20313839404245}

Code

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

C++ project_euler/problem_103/solution.cpp
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <string>
using namespace std;

/*
 * Problem 103: Special Subset Sums: Optimum
 *
 * Search for the optimal n=7 special sum set by perturbing the
 * near-optimum {20,31,38,39,40,42,45} by +/-3 on each element.
 */

bool is_special(vector<int>& a) {
    int n = a.size();
    sort(a.begin(), a.end());
    // Property 2
    for (int k = 1; k <= n / 2; k++) {
        int lo = 0, hi = 0;
        for (int i = 0; i <= k; i++) lo += a[i];
        for (int i = 0; i < k; i++) hi += a[n - 1 - i];
        if (lo <= hi) return false;
    }
    // Property 1
    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() {
    int base[] = {20, 31, 38, 39, 40, 42, 45};
    int best_sum = 255;
    vector<int> best_set(base, base + 7);
    const int D = 3;

    for (int d0 = -D; d0 <= D; d0++)
    for (int d1 = -D; d1 <= D; d1++)
    for (int d2 = -D; d2 <= D; d2++)
    for (int d3 = -D; d3 <= D; d3++)
    for (int d4 = -D; d4 <= D; d4++)
    for (int d5 = -D; d5 <= D; d5++)
    for (int d6 = -D; d6 <= D; d6++) {
        vector<int> a = {
            base[0]+d0, base[1]+d1, base[2]+d2, base[3]+d3,
            base[4]+d4, base[5]+d5, base[6]+d6
        };
        bool ok = true;
        for (int x : a) if (x <= 0) { ok = false; break; }
        if (!ok) continue;

        sort(a.begin(), a.end());
        for (int i = 1; i < 7; i++)
            if (a[i] <= a[i-1]) { ok = false; break; }
        if (!ok) continue;

        int s = 0;
        for (int x : a) s += x;
        if (s > best_sum) continue;

        if (is_special(a)) {
            if (s < best_sum || (s == best_sum && a < best_set)) {
                best_sum = s;
                best_set = a;
            }
        }
    }

    sort(best_set.begin(), best_set.end());
    string ans;
    for (int x : best_set) ans += to_string(x);
    cout << ans << endl;
    return 0;
}