Split an integer for the largest product
Given an integer n ≥ 2, write it as a sum of at least two positive integers and return the largest
possible product of those integers.
Examples
| Input | Output | Why |
|---|---|---|
n = 2 | 1 | 1 + 1. |
n = 10 | 36 | 3 + 3 + 4. |
n = 8 | 18 | 3 + 3 + 2. |
Constraints
- 2 ≤ n ≤ 58
Hints
Hint 1
best[t] = the largest product of parts summing to t, where t itself may be one part.
Hint 2
best[t] = max over the first part p of p · best[t − p], with best[0] = 1.
Hint 3
For n itself, the part n alone is not allowed.
Where people lose marks
- Allowing n as a single part, which returns n.
- best[0] = 0, which zeroes every product.
Dry run on 10
Read it one frame at a time, the way you would trace the code on paper in an interview. Each frame shows the state after the step it describes.
-
Step 1 / 10best1011
t = 1: best first part 1, 1 · best[0] = 1.
-
Step 2 / 10best101122
t = 2: best first part 2, 2 · best[0] = 2.
-
Step 3 / 10best10112233
t = 3: best first part 3, 3 · best[0] = 3.
-
Step 4 / 10best1011223344
t = 4: best first part 2, 2 · best[2] = 4.
-
Step 5 / 10best101122334465
t = 5: best first part 2, 2 · best[3] = 6.
-
Step 6 / 10best10112233446596
t = 6: best first part 3, 3 · best[3] = 9.
-
Step 7 / 10best10112233446596127
t = 7: best first part 2, 2 · best[5] = 12.
-
Step 8 / 10best10112233446596127188
t = 8: best first part 2, 2 · best[6] = 18.
-
Step 9 / 10best10112233446596127188279
t = 9: best first part 3, 3 · best[6] = 27.
-
Step 10 / 10best101122334465961271882793610
t = 10: best first part 2, 2 · best[8] = 36.
How to think about it
Parts can repeat and their order does not matter for the product, so this is the unbounded knapsack with
multiplication as the combine step. Let best[t] be the largest product of parts summing to t when a single part
is allowed; best[t] = max over p ≤ t of p · best[t − p], with best[0] = 1. The answer must use at
least two parts, so for n itself take the maximum over p < n only.
The DP confirms a classic fact: the optimal parts are 3s, with a 2 or two 2s for the remainder.
Complexity. Time O(n²) · Space O(n)
The solution, in six languages
Each one is compiled and run against the test table before it is published. Java is reviewed by hand.
def integer_break(n):
best = [1] + [0] * n # best[t]: a single part allowed
for t in range(1, n + 1):
for p in range(1, t + 1):
if t == n and p == n:
continue # n itself needs at least two parts
best[t] = max(best[t], p * best[t - p])
return best[n]#include <algorithm>
#include <vector>
long long solve(int n) {
std::vector<long long> best(n + 1, 0);
best[0] = 1;
for (int t = 1; t <= n; ++t)
for (int p = 1; p <= t; ++p) {
if (t == n && p == n) continue; // at least two parts for n
best[t] = std::max(best[t], p * best[t - p]);
}
return best[n];
}class Solution {
public long integerBreak(int n) {
long[] best = new long[n + 1];
best[0] = 1;
for (int t = 1; t <= n; t++)
for (int p = 1; p <= t; p++) {
if (t == n && p == n) continue; // at least two parts for n
best[t] = Math.max(best[t], p * best[t - p]);
}
return best[n];
}
}function integerBreak(n) {
const best = [1, ...new Array(n).fill(0)];
for (let t = 1; t <= n; t++)
for (let p = 1; p <= t; p++) {
if (t === n && p === n) continue; // at least two parts for n
best[t] = Math.max(best[t], p * best[t - p]);
}
return best[n];
}fn solve(n: i64) -> i64 {
let n = n as usize;
let mut best = vec![0i64; n + 1];
best[0] = 1;
for t in 1..=n {
for p in 1..=t {
if t == n && p == n {
continue; // at least two parts for n
}
best[t] = best[t].max(p as i64 * best[t - p]);
}
}
best[n]
}import Data.Array
solve :: Int -> Int
solve n = maximum [p * best ! (n - p) | p <- [1 .. n - 1]] -- at least two parts for n itself
where
-- best ! t: the largest product of parts summing to t, a single part allowed
best = listArray (0, n) (1 : [maximum [p * best ! (t - p) | p <- [1 .. t]] | t <- [1 .. n]]) :: Array Int Int
Variants to try
- Prove that 3s are optimal and solve it in O(1).
- The answer modulo 10⁹ + 7 for n up to 10⁹ (fast exponentiation of 3).
- Exactly k parts.
Next problems
Fewest coins to make an amount
Greedy fails, recursion repeats itself, and one array fixes both. The cleanest first dynamic programme.
Open the problem → Medium15 minCut a rod for the most money
A piece of length L sells for prices[L − 1]. Cut a rod of length n to maximise revenue: the best first piece plus the best for what remains.
Open the problem → Easy10 minThe cheapest way up a staircase
Each step has a cost; climb one or two steps at a time; start on step 0 or 1. Return the cheapest way past the top.
Open the problem →Write a solution and run it against the real test table.
Keep going
Fewest coins to make an amount
Greedy fails, recursion repeats itself, and one array fixes both. The cleanest first dynamic programme.
Open the problem → Medium15 minCut a rod for the most money
A piece of length L sells for prices[L − 1]. Cut a rod of length n to maximise revenue: the best first piece plus the best for what remains.
Open the problem → Easy10 minThe cheapest way up a staircase
Each step has a cost; climb one or two steps at a time; start on step 0 or 1. Return the cheapest way past the top.
Open the problem → Dynamic programmingThe pattern behind it
Write the recursion, notice the repeats, fill a table in an order that makes each entry final.
Read the pattern →Preparing for a real process? Quant interview preparation, or book a free 20-minute call.