10.35

From The Algorithm Design Manual Solution Wiki
Jump to navigation Jump to search

Idea. Let a[0 … n-1] be the digits of the given number and sum(i,j) be the sum of digits from position i to j (inclusive). For any interval [i,j] define   dp[i][j] = best total the current player can collect from that interval if both play optimally. When the current player removes a digit he immediately gets its value; the remainder of the interval is then played by the opponent, who will in turn take dp[…] points out of it. Hence

dp[i][j] = max( a[i] + (sum(i+1,j) − dp[i+1][j]), // take left digit a[j] + (sum(i, j-1) − dp[i][j-1]) // take right digit )
Base case: dp[i][i] = a[i]. The answer for the original number is dp[0][n-1]. Pseudocode (O(n²) time, O(n²) memory; 1-D space can be used as well)
a = list of digits n = len(a) # prefix sums for O(1) range-sum queries pref[0] = 0 for i = 0 .. n-1: pref[i+1] = pref[i] + a[i] sum(i,j) = pref[j+1] - pref[i] dp = [[0]*n for _ in range(n)] for i = 0 .. n-1: dp[i][i] = a[i] for length = 2 .. n: for i = 0 .. n-length: j = i + length - 1 left = a[i] + (sum(i+1,j) - dp[i+1][j]) right = a[j] + (sum(i, j-1) - dp[i][j-1]) dp[i][j] = max(left, right) return dp[0][n-1]
Correctness proof (sketch). Induction on the length of the remaining interval. • Base length=1: only one digit, the formula returns it. • Inductive step: assume the formula is correct for all intervals shorter than . For interval [i,j] (length ℓ) the optimal first move is either left or right digit; after it, the game on the smaller interval is optimally solved (by the induction hypothesis) giving the opponent dp[…] points, leaving the first player the rest of the sum. Taking the maximum of the two possibilities is therefore optimal, so the recurrence gives the true value. Complexity. There are Θ(n²) interval states and each is filled in O(1) time ⇒ total O(n²) time and O(n²) memory (or O(n) with the 1-D trick).


Back to Chapter 10