All Euler problems
Project Euler

Compromise or Persist

Alice is sitting in front of n bowls numbered 1 to n, each containing a single marble. She picks a random bowl, keeping the marble from it. She then continues picking random bowls; if the bowl stil...

Source sync Apr 19, 2026
Problem #0503
Level Level 27
Solved By 378
Languages C++, Python
Answer 3.8694550145
Length 416 words
modular_arithmeticprobabilitydynamic_programming

Problem Statement

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

Alice is playing a game with \(n\) cards numbered \(1\) to \(n\).

A game consists of iterations of the following steps.

1.
Alice picks one of the cards at random.
2.
Alice cannot see the number on it. Instead, Bob, one of her friends, sees the number and tells Alice how many previously-seen numbers are bigger than the number which he is seeing.
3.
Alice can end or continue the game. If she decides to end, the number becomes her score. If she decides to continue, the card is removed from the game and she returns to (1). If there is no card left, she is forced to end the game.

Let \(F(n)\) be Alice’s expected score if she takes the optimized strategy to <b>minimize</b> her score.

For example, \(F(3) = 5/3\). At the first iteration, she should continue the game. At the second iteration, she should end the game if Bob says that one previously-seen number is bigger than the number which he is seeing, otherwise she should continue the game.

We can also verify that \(F(4) = 15/8\) and \(F(10) \approx 2.5579365079\).

Find \(F(10^6)\). Give your answer rounded to \(10\) decimal places behind the decimal point.

Problem 503: Compromise or Persist

Mathematical Foundation

Theorem 1 (Coupon Collector Variant). Consider a process where Alice draws uniformly at random from nn bowls. She collects marbles from non-empty bowls. When she draws an empty bowl, she returns all collected marbles and retains only that bowl’s marble. The expected number of draws to collect kk marbles follows a backward-induction recurrence.

Proof. Define the state by the number of marbles currently held, j{1,,k}j \in \{1, \ldots, k\}, and the number of distinct bowls that have been emptied (equivalently, the current collection). From state jj (holding jj marbles, having emptied jj specific bowls):

  • With probability (nj)/n(n - j)/n, she picks a bowl still containing its marble, advancing to state j+1j + 1.
  • With probability j/nj/n, she picks an already-emptied bowl, resetting to state 11 (after returning all marbles and receiving the current bowl’s marble back).

Let EjE_j denote the expected number of additional draws to reach kk marbles from state jj. Then:

Ej=1+njnEj+1+jnE1for 1j<k,Ek=0.E_j = 1 + \frac{n - j}{n} E_{j+1} + \frac{j}{n} E_1 \quad \text{for } 1 \le j < k, \qquad E_k = 0.

This is a linear system in E1,,Ek1E_1, \ldots, E_{k-1} solvable by standard techniques. \square

Lemma 1 (Harmonic Structure). When the reset sends the player back to state 1, the expected time exhibits harmonic-number-like growth. Specifically, unrolling the recurrence yields:

E1=nn1(1+1nE1+n1nE2)E_1 = \frac{n}{n - 1}\left(1 + \frac{1}{n} E_1 + \frac{n - 1}{n} E_2\right)

Iterating the recurrence and solving the resulting linear equation for E1E_1 produces a closed-form involving partial harmonic sums:

E1=nj=1k11nj=1j1nnE_1 = n \sum_{j=1}^{k-1} \frac{1}{n - j} \cdot \prod_{\ell=1}^{j-1} \frac{n}{n - \ell}

(The exact form depends on the precise reset mechanism.)

Proof. Substitute EjE_j in terms of Ej+1E_{j+1} and E1E_1 recursively from j=k1j = k-1 down to j=1j = 1. Each step introduces a factor of n/(nj)n/(n-j), yielding the product-sum form. Collecting the E1E_1 terms on one side and solving completes the derivation. \square

Theorem 2 (Summation Identity). The aggregate n=1NP(n)\sum_{n=1}^{N} P(n) (where P(n)=Hn/nP(n) = H_n / n in the simplified model) satisfies:

n=1NHnn=12(HN2+HN(2))\sum_{n=1}^{N} \frac{H_n}{n} = \frac{1}{2}\left(H_N^2 + H_N^{(2)}\right)

where HN=k=1N1/kH_N = \sum_{k=1}^{N} 1/k and HN(2)=k=1N1/k2H_N^{(2)} = \sum_{k=1}^{N} 1/k^2.

Proof. Write Hn=k=1n1/kH_n = \sum_{k=1}^{n} 1/k and interchange the order of summation:

n=1NHnn=n=1N1nk=1n1k=1knN1kn.\sum_{n=1}^{N} \frac{H_n}{n} = \sum_{n=1}^{N} \frac{1}{n} \sum_{k=1}^{n} \frac{1}{k} = \sum_{1 \le k \le n \le N} \frac{1}{kn}.

Split into diagonal (k=nk = n) and off-diagonal (k<nk < n) terms:

=k=1N1k2+1k<nN1kn=HN(2)+12[(k=1N1k)2HN(2)]=HN2+HN(2)2.= \sum_{k=1}^{N} \frac{1}{k^2} + \sum_{1 \le k < n \le N} \frac{1}{kn} = H_N^{(2)} + \frac{1}{2}\left[\left(\sum_{k=1}^{N} \frac{1}{k}\right)^2 - H_N^{(2)}\right] = \frac{H_N^2 + H_N^{(2)}}{2}.

\square

Editorial

Optimal stopping / negotiation game with alternating offers. Involves harmonic numbers and backward induction. We compute harmonic numbers H_n and H_n^(2) modularly. Finally, alternative via closed form.

Pseudocode

Compute harmonic numbers H_n and H_n^(2) modularly
Alternative via closed form:
total = (H_N^2 + H_N^(2)) / 2 mod p

Complexity Analysis

  • Time: O(Nlogp)O(N \log p) for the iterative computation with modular inverses (each modinv\text{modinv} costs O(logp)O(\log p) via Fermat’s little theorem when pp is prime).
  • Space: O(1)O(1) if computing on the fly; O(N)O(N) if storing all harmonic prefixes.

Answer

3.8694550145\boxed{3.8694550145}

Code

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

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

int main() {
    // Compute sum of P(n) = H_n / n for n = 1..N
    // where H_n is the n-th harmonic number
    const int N = 1000;
    double harmonic = 0.0;
    double total = 0.0;

    for (int n = 1; n <= N; n++) {
        harmonic += 1.0 / n;
        total += harmonic / n;  // P(n) = H_n / n
    }

    cout << fixed << setprecision(10) << total << endl;

    // Verify with backward induction DP for small n
    int test_n = 5;
    int R = 200;
    vector<double> v(R + 1, 0.0);
    for (int r = 1; r <= R; r++) {
        double best = 0.0;
        for (int s = 1; s <= test_n; s++) {
            double p = (double)s / test_n;
            double payoff = p * ((double)s / test_n) + (1 - p) * v[r - 1];
            best = max(best, payoff);
        }
        v[r] = best;
    }
    cout << "DP verification for n=" << test_n << ": " << v[R] << endl;

    return 0;
}