Optimal strategy for a Game with modifications
Last Updated :
24 Jul, 2024
It is strongly recommended to first refer Optimal Strategy for a Game problem as a prerequisite. Let us now talk about a variation problem. Consider a row of n coins of values v1 . . . vn, where n is even. We play a game against an opponent by alternating turns. In each turn, a player performs the following operation K times.
The player selects either the first or last coin from the row, removes it from the row permanently, and receives the value of the coin.
Determine the maximum possible amount of money the user can definitely win if the user moves first.
Note: The opponent is as clever as the user.
Examples:
Input : array = {10, 15, 20, 9, 2, 5}, k=2
Output :32
Explanation:
Lets say, user has initially picked 10 and 15.
The value of coins which the user has is 25 and
{20, 9, 2, 5} are remaining in the array.
In the second round, the opponent picks 20 and 9 making his value 29.
In the third round, the user picks 2 and 5 which makes his total value as 32.
Input: array = {10, 15, 20, 9, 2}, k=1
Output: 32
Approach:
A recursive solution needs to be formed and the values of sub problems needs to be stored to compute the result.
Taking an example to arrive at the recursive solution;
arr = {10, 15, 20, 9, 2, 5}, k=2
So if the user selects 10, 15 in the first turn then 20, 9, 2, 5 are left in the array.
But if the user selects 10, 5; then 15, 20, 9, 2 are left in the array.
Lastly, if the user selects 5, 2; then 10, 15, 20, 9 are left in the array.
So at any iteration after selecting k elements, a continuous subarray of length n-k is remaining for next computation.
So recursive solution can be formed where :
S(l, r) = (sum(l, r) - sum(l+i, l+i+n-k-1))+(sum(l+i, l+i+n-k-1) - S(l+i, l+i+n-k-1))
where l+i+n-k-1<=r
Sum of chosen elements Sc=(sum(l, r) - sum(l+i, l+i+n-k-1))
Now the opponent will perform the next turn so
Sum of Elements chosen in next steps = Total sum of present array from l to r -
Sum of elements chosen by opponent in next steps which is equal to
Nc=(sum(l+i, l+i+n-k-1) - S(l+i, l+i+n-k-1)).
S(l, r) = Sc + Nc
where,
Nc=(sum(l+i, l+i+n-k-1) - S(l+i, l+i+n-k-1))
Sc=(sum(l, r) - sum(l+i, l+i+n-k-1))
Below is the implementation of the above approach:
C++
// C++ implementation of the above approach
#include <bits/stdc++.h>
using namespace std;
#define ll long long int
// Function to return sum of subarray from l to r
ll sum(int arr[], int l, int r)
{
// calculate sum by a loop from l to r
ll s = 0;
for (int i = l; i <= r; i++) {
s += arr[i];
}
return s;
}
// dp to store the values of sub problems
ll dp[101][101][101] = { 0 };
ll solve(int arr[], int l, int r, int k)
{
// if length of the array is less than k
// return the sum
if (r - l + 1 <= k)
return sum(arr, l, r);
// if the value is previously calculated
if (dp[l][r][k])
return dp[l][r][k];
// else calculate the value
ll sum_ = sum(arr, l, r);
ll len_r = (r - l + 1) - k;
ll len = (r - l + 1);
ll ans = 0;
// select all the sub array of length len_r
for (int i = 0; i < len - len_r + 1; i++) {
// get the sum of that sub array
ll sum_sub = sum(arr, i + l, i + l + len_r - 1);
// check if it is the maximum or not
ans = max(ans, (sum_ - sum_sub) + (sum_sub -
solve(arr, i + l, i + l + len_r - 1, k)));
}
// store it in the table
dp[l][r][k] = ans;
return ans;
}
// Driver code
int main()
{
int arr[] = { 10, 15, 20, 9, 2, 5 }, k = 2;
int n = sizeof(arr) / sizeof(int);
memset(dp, 0, sizeof(dp));
cout << solve(arr, 0, n - 1, k);
return 0;
}
Java
// Java implementation of the above approach
class GFG
{
// Function to return sum of subarray from l to r
static int sum(int arr[], int l, int r)
{
// calculate sum by a loop from l to r
int s = 0;
for (int i = l; i <= r; i++)
{
s += arr[i];
}
return s;
}
// dp to store the values of sub problems
static int dp[][][] = new int[101][101][101] ;
static int solve(int arr[], int l, int r, int k)
{
// if length of the array is less than k
// return the sum
if (r - l + 1 <= k)
return sum(arr, l, r);
// if the value is previously calculated
if (dp[l][r][k] != 0)
return dp[l][r][k];
// else calculate the value
int sum_ = sum(arr, l, r);
int len_r = (r - l + 1) - k;
int len = (r - l + 1);
int ans = 0;
// select all the sub array of length len_r
for (int i = 0; i < len - len_r + 1; i++)
{
// get the sum of that sub array
int sum_sub = sum(arr, i + l, i + l + len_r - 1);
// check if it is the maximum or not
ans = Math.max(ans, (sum_ - sum_sub) + (sum_sub -
solve(arr, i + l, i + l + len_r - 1, k)));
}
// store it in the table
dp[l][r][k] = ans;
return ans;
}
// Driver code
public static void main (String[] args)
{
int arr[] = { 10, 15, 20, 9, 2, 5 }, k = 2;
int n = arr.length;
System.out.println(solve(arr, 0, n - 1, k));
}
}
// This code is contributed by AnkitRai01
Python
# Python3 implementation of the above approach
import numpy as np
# Function to return sum of subarray from l to r
def Sum(arr, l, r) :
# calculate sum by a loop from l to r
s = 0;
for i in range(l, r + 1) :
s += arr[i];
return s;
# dp to store the values of sub problems
dp = np.zeros((101, 101, 101));
def solve(arr, l, r, k) :
# if length of the array is less than k
# return the sum
if (r - l + 1 <= k) :
return Sum(arr, l, r);
# if the value is previously calculated
if (dp[l][r][k]) :
return dp[l][r][k];
# else calculate the value
sum_ = Sum(arr, l, r);
len_r = (r - l + 1) - k;
length = (r - l + 1);
ans = 0;
# select all the sub array of length len_r
for i in range(length - len_r + 1) :
# get the sum of that sub array
sum_sub = Sum(arr, i + l, i + l + len_r - 1);
# check if it is the maximum or not
ans = max(ans, (sum_ - sum_sub) + (sum_sub -
solve(arr, i + l, i + l + len_r - 1, k)));
# store it in the table
dp[l][r][k] = ans;
return ans;
# Driver code
if __name__ == "__main__" :
arr = [ 10, 15, 20, 9, 2, 5 ]; k = 2;
n = len(arr);
print(solve(arr, 0, n - 1, k));
# This code is contributed by AnkitRai01
C#
// C# implementation of the above approach
using System;
class GFG
{
// Function to return sum of subarray from l to r
static int sum(int []arr, int l, int r)
{
// calculate sum by a loop from l to r
int s = 0;
for (int i = l; i <= r; i++)
{
s += arr[i];
}
return s;
}
// dp to store the values of sub problems
static int [,,]dp = new int[101, 101, 101] ;
static int solve(int []arr, int l, int r, int k)
{
// if length of the array is less than k
// return the sum
if (r - l + 1 <= k)
return sum(arr, l, r);
// if the value is previously calculated
if (dp[l, r, k] != 0)
return dp[l, r, k];
// else calculate the value
int sum_ = sum(arr, l, r);
int len_r = (r - l + 1) - k;
int len = (r - l + 1);
int ans = 0;
// select all the sub array of length len_r
for (int i = 0; i < len - len_r + 1; i++)
{
// get the sum of that sub array
int sum_sub = sum(arr, i + l, i + l + len_r - 1);
// check if it is the maximum or not
ans = Math.Max(ans, (sum_ - sum_sub) + (sum_sub -
solve(arr, i + l, i + l + len_r - 1, k)));
}
// store it in the table
dp[l, r, k] = ans;
return ans;
}
// Driver code
public static void Main ()
{
int []arr = { 10, 15, 20, 9, 2, 5 };
int k = 2;
int n = arr.Length;
Console.WriteLine(solve(arr, 0, n - 1, k));
}
}
// This code is contributed by AnkitRai01
JavaScript
<script>
// JavaScript implementation of the above approach
// Function to return sum of subarray from l to r
function sum(arr, l, r)
{
// calculate sum by a loop from l to r
let s = 0;
for (let i = l; i <= r; i++)
{
s += arr[i];
}
return s;
}
// dp to store the values of sub problems
let dp = new Array(101);
for (let i = 0; i < 101; i++)
{
dp[i] = new Array(101);
for (let j = 0; j < 101; j++)
{
dp[i][j] = new Array(101);
for (let k = 0; k < 101; k++)
{
dp[i][j][k] = 0;
}
}
}
function solve(arr, l, r, k)
{
// if length of the array is less than k
// return the sum
if (r - l + 1 <= k)
return sum(arr, l, r);
// if the value is previously calculated
if (dp[l][r][k] != 0)
return dp[l][r][k];
// else calculate the value
let sum_ = sum(arr, l, r);
let len_r = (r - l + 1) - k;
let len = (r - l + 1);
let ans = 0;
// select all the sub array of length len_r
for (let i = 0; i < len - len_r + 1; i++)
{
// get the sum of that sub array
let sum_sub = sum(arr, i + l, i + l + len_r - 1);
// check if it is the maximum or not
ans = Math.max(ans, (sum_ - sum_sub) + (sum_sub -
solve(arr, i + l, i + l + len_r - 1, k)));
}
// store it in the table
dp[l][r][k] = ans;
return ans;
}
let arr = [ 10, 15, 20, 9, 2, 5 ], k = 2;
let n = arr.length;
document.write(solve(arr, 0, n - 1, k));
</script>
Time Complexity: O(r2)
Auxiliary Space: O(101 * 101 * 101)
Similar Reads
Optimal Strategy for a Game
Given an array arr[] of size n which represents a row of n coins of values V1 . . . Vn, where n is even. We play a game against an opponent by alternating turns. In each turn, a player selects either the first or last coin from the row, removes it from the row permanently, and receives the value of
15+ min read
Optimal Strategy for a Game | Set 3
Consider a row of n coins of values v1 . . . vn, where n is even. We play a game against an opponent by alternating turns. In each turn, a player selects either the first or last coin from the row, removes it from the row permanently, and receives the value of the coin. Determine the maximum possibl
15+ min read
Optimal Strategy for a Game | Set 2
Problem statement: Consider a row of n coins of values v1 . . . vn, where n is even. We play a game against an opponent by alternating turns. In each turn, a player selects either the first or last coin from the row, removes it from the row permanently, and receives the value of the coin. Determine
15+ min read
Game Theory (Normal - form game) | Set 1 (Introduction)
Game theory is a mathematical model used for decision making. It has applications in all fields of social science, as well as in logic and computer science. Game theory has come to play an increasingly important role in logic and in computer science. To be fully defined, a game must specify the foll
4 min read
Game Theory (Normal-form game) | Set 3 (Game with Mixed Strategy)
Consider the following payoff matrix with respect to player A and solve it optimally. Solution: If a game has no saddle point then the game is said to have mixed strategy. Step 1: Find out the row minimum and column maximum. Step 2: Find out the minimax and maximin values. Since minimax and maximin
4 min read
Game Theory (Normal form game) | Set 2 (Game with Pure Strategy)
Game Theory (Normal â form game) | Set 1 (Introduction) Please go through the above article before proceeding. Given a payoff matrix. The task is to find the optimum strategies of the players. Solution: Player A is having 3 strategies - 1, 2 and 3, and player B is also having 3 strategies - 1, 2 and
2 min read
Pareto Optimality and its application in Game Theory
Prerequisites: Game Theory When the strategies from game theory are discussed, they are often mentioned from a player's perspective. However, when the strategies are formed from an observer's angle whose main motive is to wish for the best outcome for every player; that is, when strategies are forme
5 min read
Optimal Strategy for the Divisor game using Dynamic Programming
Given an integer N and two players, A and B are playing a game. On each playerâs turn, that player makes a move by subtracting a divisor of current N (which is less than N) from current N, thus forming a new N for the next turn. The player who does not have any divisor left to subtract loses the gam
9 min read
Minimax Algorithm in Game Theory | Set 1 (Introduction)
Minimax is a kind of backtracking algorithm that is used in decision making and game theory to find the optimal move for a player, assuming that your opponent also plays optimally. It is widely used in two player turn-based games such as Tic-Tac-Toe, Backgammon, Mancala, Chess, etc.In Minimax the tw
9 min read
Game Theory (Normal-form Game) | Set 4 (Dominance Property-Pure Strategy)
In some of the games, it is possible to reduce the size of the payoff matrix by eliminating rows (or columns) that are dominated by other rows (or columns) respectively. Dominance property for rows: X ⤠Y i.e. if all the elements of a particular row X are less than or equal to the corresponding elem
4 min read