Soup Servings

MediumProbability DP · Memoisation🧩 Probability DPLeetCode #808 ↗Updated

Problem

Two soups, A and B, each start with n ml. Each turn one of four servings is picked with probability 1/4: (A 100, B 0), (A 75, B 25), (A 50, B 50) or (A 25, B 75) ml. If a soup has less than requested, serve what is left. Stop as soon as either soup is empty. Return P(A empties first) + ½ · P(both empty together).
Inputn = 50Output0.62500
Inputn = 100Output0.71875

0 ≤ n ≤ 109  ·  answers within 10-5 are accepted

Try it yourself

Java
class Solution {
    public double soupServings(int n) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
Every serving is a multiple of 25, so work in units of 25 ml (m = ⌈n/25⌉). On average A loses 2.5 units and B 1.5 per turn, so A is heavily favoured: once n > 4800 the answer is within 10-5 of 1 and we can return 1 directly.
PatternProbability DP

Instinct Asked for a probability or expected value after random moves? Run DP over (step, state) and split each state's mass across every outcome.

Memory hack Pour the probability like water - split it across the moves, let what spills off the board drain away, and the puddle that's left is your answer.

Open the Probability DP guide →

Approaches

Brute ForcePlain Recursion over All Serving Sequences

Time O(4n/100)Space O(n/100)

f(a, b) returns 0.5 if both are empty, 1 if only A is empty, 0 if only B is empty, else the average of the four next states. Every turn removes 100 ml in total, so the depth is about 2n/100 and each level branches 4 ways.

Java
public double soupServings(int n) {
    return serve(n, n);
}

private double serve(int a, int b) {
    if (a <= 0 && b <= 0) return 0.5;
    if (a <= 0) return 1.0;
    if (b <= 0) return 0.0;
    return 0.25 * (serve(a - 100, b) + serve(a - 75, b - 25)
                 + serve(a - 50, b - 50) + serve(a - 25, b - 75));
}

Faithful to the rules but exponential — only works for a few hundred ml.

At a glance

LevelApproachTimeSpace
Brute ForcePlain Recursion over All Serving SequencesO(4n/100)O(n/100)
BetterMemoisation in 25 ml UnitsO(m2)O(m2)
OptimalMemoisation + Convergence Cut-offO(1)O(1)
Common pitfalls
  • Using n / 25 instead of rounding up — 1 ml of soup still counts as a unit.
  • Returning 1 for “both empty” instead of 0.5.
  • Allocating an m×m table for n = 109 without the cut-off (memory error).
Interview tips
  • Spot the gcd of all servings (25) early — it shrinks the state space 625×.
  • Explain the asymmetry: expected A per turn is 62.5 ml vs 37.5 ml for B.
  • Justify the cut-off with the 10-5 tolerance stated in the problem.
Pattern
Probability DP + convergence → huge input range but a tolerance on the answer hints that the value saturates.
My notes saved in this browser