# Optimal strategy for a Game with modifications

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 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

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

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))
```

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Below is the implementation of the above approach:

 `// C++ implementation of the above approach ` `#include ` `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 = { 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 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 `

 `# 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# 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 `

Output:
```32
```

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

Third year Department of Information Technology Jadavpur University

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.

Improved By : AnkitRai01

Article Tags :