Prime Summations
It is possible to write ten as the sum of primes in exactly five different ways: What is the first value which can be written as the sum of primes in over five thousand different ways?
Problem Statement
This archive keeps the full statement, math, and original media on the page.
It is possible to write ten as the sum of primes in exactly five different ways: \begin {align*} &7 + 3\\ &5 + 5\\ &5 + 3 + 2\\ &3 + 3 + 2 + 2\\ &2 + 2 + 2 + 2 + 2 \end {align*}
What is the first value which can be written as the sum of primes in over five thousand different ways?
Problem 77: Prime Summations
Mathematical Foundation
Definition 1 (Prime Partition Function). Let denote the number of partitions of into prime parts, i.e., the number of ways to express as an unordered sum of primes with repetition allowed. By convention, (the empty sum).
Theorem 1 (Generating Function for Prime Partitions). The ordinary generating function for is
Proof. For each prime , the factor encodes the choice of copies of contributing to the sum. Taking the product over all primes, the coefficient of in the resulting series counts the number of solutions in non-negative integers to , which is .
Absolute convergence for follows from , so the infinite product converges.
Definition 2 (Restricted Prime Partition). Let denote the number of partitions of using only primes from , where is the sequence of primes.
Theorem 2 (Correctness of the Prime Partition DP). Initialize and for . For each prime in increasing order, update for . Then for all .
Proof. We prove by induction on the index (over the prime sequence ) that after processing prime , the value for all .
Base case (): Before processing any prime, and for .
Inductive step: Suppose for all . The update for (in increasing order) adds the count of partitions containing at least one copy of . The forward iteration permits unbounded repetition of , since already reflects earlier uses of in the same pass. After this pass:
by the identity that conditions on the multiplicity of .
After all primes are processed, for , since no prime exceeding can appear in a partition of .
Lemma 1 (Sufficient Search Bound). There exists with .
Proof. The function is monotonically non-decreasing for (since every partition of into primes can be extended by adding to some part or by inclusion). Direct computation yields , confirming the bound.
Editorial
The structure is the same as the ordinary partition DP, except the allowed part sizes are now primes. We first generate all primes up to a safe search bound, then process them one by one in increasing order. After a prime has been processed, each table entry counts the representations that use only primes up to .
Adding prime works exactly like the unbounded-knapsack transition: every way to make can be extended by one more copy of , so it contributes to the count for . Using primes in increasing order prevents different orders of the same sum from being counted separately. Once the table is filled, we scan upward and stop at the first value whose count exceeds 5000.
Pseudocode
Choose a search bound that is known to contain the answer.
Generate every prime up to that bound.
Create a counting table for totals up to the bound and set the value for 0 to 1.
For each prime:
For each total that is at least that prime:
add the number of representations for the reduced total
Scan the totals from 2 upward.
Return the first total whose count is greater than 5000.
Complexity Analysis
Time: The Sieve of Eratosthenes computes all primes up to in time. The DP phase performs iterations, each in . By the Prime Number Theorem, , so the DP cost is . For : , yielding at most operations.
Space: for the DP array and the prime list.
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
int main() {
const int N = 100;
// Sieve of Eratosthenes
vector<bool> is_prime(N + 1, true);
is_prime[0] = is_prime[1] = false;
for (int i = 2; i * i <= N; i++)
if (is_prime[i])
for (int j = i * i; j <= N; j += i)
is_prime[j] = false;
vector<int> primes;
for (int i = 2; i <= N; i++)
if (is_prime[i])
primes.push_back(i);
// DP: unbounded knapsack with prime denominations
vector<long long> dp(N + 1, 0);
dp[0] = 1;
for (int p : primes)
for (int j = p; j <= N; j++)
dp[j] += dp[j - p];
// Find first n with q(n) > 5000
for (int n = 2; n <= N; n++) {
if (dp[n] > 5000) {
cout << n << endl;
return 0;
}
}
return 0;
}
"""
Problem 77: Prime Summations
What is the first value which can be written as the sum of primes
in over five thousand different ways?
Answer: 71
"""
def sieve(n):
"""Return list of primes up to n via the Sieve of Eratosthenes."""
is_prime = [True] * (n + 1)
is_prime[0] = is_prime[1] = False
for i in range(2, int(n**0.5) + 1):
if is_prime[i]:
for j in range(i * i, n + 1, i):
is_prime[j] = False
return [i for i in range(2, n + 1) if is_prime[i]]
def main():
N = 100
primes = sieve(N)
# DP: unbounded knapsack with prime denominations
dp = [0] * (N + 1)
dp[0] = 1
for p in primes:
for j in range(p, N + 1):
dp[j] += dp[j - p]
# Find first n with q(n) > 5000
for n in range(2, N + 1):
if dp[n] > 5000:
print(n)
return
print(-1)
if __name__ == "__main__":
main()