All Euler problems
Project Euler

Special Subset Sums: Meta-testing

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)!= S(C);...

Source sync May 21, 2026
Problem #0106
Level Level 05
Solved By 7,527
Languages C++, Python
Answer 21384
Length 803 words
combinatoricssequencebrute_force

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 this problem we shall assume that a given set contains \(n\) strictly increasing elements and it already satisfies the second rule.

Surprisingly, out of the \(25\) possible subset pairs that can be obtained from a set for which \(n = 4\), only \(1\) of these pairs need to be tested for equality (first rule). Similarly, when \(n = 7\), only \(70\) out of the \(966\) subset pairs need to be tested.

For \(n = 12\), how many of the \(261625\) subset pairs that can be obtained need to be tested for equality?

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

Problem 106: Special Subset Sums: Meta-testing

Mathematical Foundation

Theorem 1. (Reduction to Equal-Size Pairs) If Property 2 holds for a set AA, then S(B)≠S(C)S(B) \neq S(C) for all non-empty disjoint subsets B,CB, C with ∣B∣≠∣C∣|B| \neq |C|.

Proof. Without loss of generality, assume ∣B∣>∣C∣|B| > |C|. Property 2 directly gives S(B)>S(C)S(B) > S(C), hence S(B)≠S(C)S(B) \neq S(C). □\square

Theorem 2. (Counting Equal-Size Disjoint Pairs) The number of unordered pairs {B,C}\{B, C\} of disjoint subsets of an nn-element set with ∣B∣=∣C∣=k|B| = |C| = k is:

Nk=12(nk)(n−kk)=(n2k)⋅12(2kk)N_k = \frac{1}{2}\binom{n}{k}\binom{n-k}{k} = \binom{n}{2k} \cdot \frac{1}{2}\binom{2k}{k}

Proof. To choose an ordered pair (B,C)(B, C): first choose BB as any kk-subset of [n][n] in (nk)\binom{n}{k} ways, then choose CC as any kk-subset of the remaining n−kn - k elements in (n−kk)\binom{n-k}{k} ways. This counts each unordered pair {B,C}\{B, C\} twice (once as (B,C)(B, C) and once as (C,B)(C, B)), so Nk=12(nk)(n−kk)N_k = \frac{1}{2}\binom{n}{k}\binom{n-k}{k}.

For the alternative form: first choose the 2k2k elements that will participate in (n2k)\binom{n}{2k} ways, then partition them into two groups of kk in 12(2kk)\frac{1}{2}\binom{2k}{k} ways (dividing by 2 for the unordered pair). □\square

Theorem 3. (Non-Crossing Pairs are Automatically Verified) Let A={a1<a2<⋯<an}A = \{a_1 < a_2 < \cdots < a_n\} satisfy Property 2. Consider two disjoint subsets B,C⊂AB, C \subset A with ∣B∣=∣C∣=k|B| = |C| = k. Sort the elements of BB as b1<⋯<bkb_1 < \cdots < b_k and of CC as c1<⋯<ckc_1 < \cdots < c_k. If bi<cib_i < c_i for all ii (or bi>cib_i > c_i for all ii), then S(B)≠S(C)S(B) \neq S(C) is automatically guaranteed.

Proof. Suppose bi<cib_i < c_i for all i=1,…,ki = 1, \ldots, k. Then S(B)=∑bi<∑ci=S(C)S(B) = \sum b_i < \sum c_i = S(C), since bi<cib_i < c_i for every index. Hence S(B)≠S(C)S(B) \neq S(C) without any additional verification. The case bi>cib_i > c_i for all ii is symmetric. □\square

Theorem 4. (Connection to Catalan Numbers) Given 2k2k elements in sorted order, the number of ways to partition them into two groups of kk such that the element-wise comparison is non-crossing (i.e., bi<cib_i < c_i for all ii, or bi>cib_i > c_i for all ii, when both sequences are sorted) equals 2⋅Ck2 \cdot C_k for ordered pairs or CkC_k for unordered pairs, where Ck=1k+1(2kk)C_k = \frac{1}{k+1}\binom{2k}{k} is the kk-th Catalan number.

Proof. Label the 2k2k sorted elements by their group membership: each element gets label BB or CC, with exactly kk of each. We claim that the partition has the non-crossing property (say bi<cib_i < c_i for all ii) if and only if, when we read the labels in sorted order of the elements, we never have more CC-labels than BB-labels in any prefix.

To see this: sort all 2k2k elements as e1<e2<⋯<e2ke_1 < e_2 < \cdots < e_{2k}. Assign BB-labels and CC-labels. The sorted BB-sequence is b1<⋯<bkb_1 < \cdots < b_k (the elements labeled BB in order) and similarly for CC. The condition bi<cib_i < c_i for all ii means that the ii-th BB-element appears before the ii-th CC-element in the sorted order. This is equivalent to requiring that in every prefix of the label sequence, the count of BB‘s is at least the count of CC‘s.

The number of such sequences is exactly the kk-th Catalan number Ck=1k+1(2kk)C_k = \frac{1}{k+1}\binom{2k}{k}, by the ballot problem / Bertrand ballot theorem. (The total number of label sequences with kk BB‘s and kk CC‘s is (2kk)\binom{2k}{k}, and the fraction with all prefixes having at least as many BB‘s as CC‘s is 1k+1\frac{1}{k+1}.)

For unordered pairs, the CkC_k non-crossing partitions with bi<cib_i < c_i are in bijection with the CkC_k partitions with bi>cib_i > c_i (swap labels). Each unordered pair is counted once, so the number of unordered non-crossing pairs is CkC_k. □\square

Theorem 5. (Main Formula) The number of equal-size disjoint pairs that need testing is:

T=∑k=2⌊n/2⌋(n2k)[12(2kk)−Ck]T = \sum_{k=2}^{\lfloor n/2 \rfloor} \binom{n}{2k}\left[\frac{1}{2}\binom{2k}{k} - C_k\right]

where Ck=1k+1(2kk)C_k = \frac{1}{k+1}\binom{2k}{k}.

Proof. For each subset size kk, the total number of unordered equal-size disjoint pairs is (n2k)⋅12(2kk)\binom{n}{2k} \cdot \frac{1}{2}\binom{2k}{k} (Theorem 2). Of these, (n2k)⋅Ck\binom{n}{2k} \cdot C_k are non-crossing and hence automatically verified (Theorems 3-4). The difference gives the number needing testing.

For k=1k = 1: 12(21)−C1=1−1=0\frac{1}{2}\binom{2}{1} - C_1 = 1 - 1 = 0, so no singleton pairs need testing (if b1<c1b_1 < c_1 then trivially S(B)<S(C)S(B) < S(C)). Hence the sum starts at k=2k = 2. □\square

Editorial

Once Property 2 is assumed, unequal subset sizes no longer matter: those sums are already forced to be different. So the only pairs that can require an explicit equality check are disjoint pairs of the same size. For a fixed kk, we choose the 2k2k participating elements, count all unordered ways to split them into two kk-subsets, and then subtract the splits that are automatically ordered term by term and therefore cannot possibly have equal sums.

The Catalan-number argument from the mathematical section counts exactly those automatically safe splits. That leaves a closed formula for the number of genuinely ambiguous pairs, and the program simply evaluates that formula for each k=2,3,…,⌊n/2⌋k = 2, 3, \ldots, \lfloor n/2 \rfloor. The worked table below is just the numerical evaluation of those contributions for n=12n = 12.

Pseudocode

Set the total number of required tests to zero.

For each subset size k from 2 up to floor(n/2):
    Count the ways to choose the 2k elements that appear in the pair.
    Count all unordered splits of those elements into two k-subsets.
    Count the non-crossing splits, using the Catalan number C_k, that are automatically ordered and need no test.
    Add the difference to the running total.

Return the total.

Computation for n=12n = 12:

kk(122k)\binom{12}{2k}12(2kk)\frac{1}{2}\binom{2k}{k}CkC_kDifferenceContribution
2495321495
392410554620
449535142110395
56612642845544
61462132330330
T=495+4620+10395+5544+330=21384T = 495 + 4620 + 10395 + 5544 + 330 = 21384

Complexity Analysis

  • Time: O(n)O(n) to iterate over kk values from 2 to ⌊n/2⌋\lfloor n/2 \rfloor, assuming O(1)O(1) computation of binomial coefficients (precomputed or via closed-form). For n=12n = 12, this is 5 iterations.
  • Space: O(1)O(1), storing only a running total and temporary values.

Answer

21384\boxed{21384}

Code

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

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

// Compute binomial coefficient C(n, k)
long long comb(int n, int k) {
    if (k < 0 || k > n) return 0;
    if (k == 0 || k == n) return 1;
    if (k > n - k) k = n - k;
    long long result = 1;
    for (int i = 0; i < k; i++) {
        result = result * (n - i) / (i + 1);
    }
    return result;
}

// Catalan number C_k = C(2k,k) / (k+1)
long long catalan(int k) {
    return comb(2 * k, k) / (k + 1);
}

int main() {
    int n = 12;
    long long total = 0;

    for (int k = 2; k <= n / 2; k++) {
        long long choose_2k = comb(n, 2 * k);
        long long half_choose = comb(2 * k, k) / 2;
        long long cat_k = catalan(k);
        total += choose_2k * (half_choose - cat_k);
    }

    cout << total << endl;
    return 0;
}