Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to find minimum difference of stone games score in Python
Suppose we have an array called stones where stones[i] represents the value of the ith stone from the left. Two friends Amal and Bimal are playing a turn-based game with these stones and Amal starts first always. There are n stones arranged in a row. Each player can remove either the leftmost stone or the rightmost stone from the row and get points equal to the sum of the remaining stones' values in the row. The player with the higher score wins.
Bimal found that he will always lose this game, so he decided to minimize the score's difference. Amal's goal is to maximize the difference in the score. We have to find the difference in Amal and Bimal's score if they both play optimally.
Example Walkthrough
If the input is stones = [6,4,2,5,3], then the output will be 8. Here's how the game proceeds:
- Amal takes 3 (rightmost), his score = 6+4+2+5 = 17, remaining stones = [6,4,2,5]
- Bimal takes 6 (leftmost), his score = 4+2+5 = 11, remaining stones = [4,2,5]
- Amal takes 4 (leftmost), his score = 17+(2+5) = 24, remaining stones = [2,5]
- Bimal takes 2 (leftmost), his score = 11+5 = 16, remaining stones = [5]
- Amal takes 5 (last stone), his score = 24+0 = 24
The difference of their scores is 24-16 = 8.
Algorithm
We use dynamic programming to solve this optimally. The approach follows these steps:
- n := size of stones
- dp := an array of size n filled with 0
- For i from n-1 to 0 (reverse order):
- v := stones[i]
- run_sum := 0
- For j from i+1 to n-1:
- new_run := run_sum + stones[j]
- dp[j] := max(new_run - dp[j], run_sum + v - dp[j-1])
- run_sum := new_run
- Return dp[n-1]
Implementation
def solve(stones):
n = len(stones)
dp = [0] * n
for i in range(n - 1, -1, -1):
v = stones[i]
run_sum = 0
for j in range(i + 1, n):
new_run = run_sum + stones[j]
dp[j] = max(new_run - dp[j], run_sum + v - dp[j - 1])
run_sum = new_run
return dp[n - 1]
# Test the function
stones = [6, 4, 2, 5, 3]
result = solve(stones)
print(f"Input stones: {stones}")
print(f"Maximum score difference: {result}")
Input stones: [6, 4, 2, 5, 3] Maximum score difference: 8
How It Works
The dynamic programming solution works by considering all possible game states. The dp[j] represents the maximum score difference that the current player can achieve when considering stones from position i to j. The algorithm evaluates both choices (taking leftmost or rightmost stone) and selects the one that maximizes the current player's advantage.
Test with Different Input
def solve(stones):
n = len(stones)
dp = [0] * n
for i in range(n - 1, -1, -1):
v = stones[i]
run_sum = 0
for j in range(i + 1, n):
new_run = run_sum + stones[j]
dp[j] = max(new_run - dp[j], run_sum + v - dp[j - 1])
run_sum = new_run
return dp[n - 1]
# Test with different cases
test_cases = [
[6, 4, 2, 5, 3],
[1, 2, 3],
[5, 3, 1, 4, 6]
]
for stones in test_cases:
result = solve(stones)
print(f"Stones: {stones} ? Score difference: {result}")
Stones: [6, 4, 2, 5, 3] ? Score difference: 8 Stones: [1, 2, 3] ? Score difference: 2 Stones: [5, 3, 1, 4, 6] ? Score difference: 1
Conclusion
This stone game problem uses dynamic programming to find the optimal strategy for both players. The algorithm efficiently computes the maximum score difference when both players play optimally, with a time complexity of O(n²).
