Optimal Strategy for a Game | Set 3
Last Updated :
12 Jul, 2025
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 possible amount of money we can definitely win if we move first.
Also, print the sequence of moves in the optimal game. As many sequences of moves may lead to the optimal answer, you may print any valid sequence.
Before the sequence, the part is already discussed in these articles.
- Optimal Strategy for a Game
- Optimal Strategy for a Game | Set-2
Examples:
Input: 10 80 90 30
Output: 110 RRRL
Explanation:
P1 picks 30, P2 picks 90, P1 picks 80 and finally P2 picks 10.
Score obtained by P1 is 80 + 30 = 110
Max possible score for player 1 is : 110
Optimal game moves are : RRRL
Input: 10 100 10
Output: 20 RRL
Approach:
In each turn(except the last) a player will have two options either to pick the bag on the left or to pick the bag on the right of the row. Our focus is to evaluate the maximum score attainable by P1, let it be S. P1 would like to choose the maximum possible score in his turn whereas P2 would like to choose the minimum score possible for P1.
So P1 focuses on maximizing S, while P2 focuses on minimizing S.
Naive Approach:
- We can write a brute force recursive solution to the problem which simulates all the possibilities of the game and finds the score that is maximum under the given constraints.
- The function maxScore returns the maximum possible score for player 1 and also the moves that take place through the course of the game.
- Since the function needs to return both the maximum possible score and the moves that lead to that score, we use a pair of integer and string.
- The string that represents the moves of the game consists of chars 'L' and 'R' meaning that the leftmost or the rightmost bag was picked respectively.
Below is the implementation of the above approach:
C++
// C++ implementation
#include <bits/stdc++.h>
using namespace std;
// Calculates the maximum score
// possible for P1 If only the
// bags from beg to ed were available
pair<int, string> maxScore(vector<int> money,
int beg,
int ed)
{
// Length of the game
int totalTurns = money.size();
// Which turn is being played
int turnsTillNow = beg
+ ((totalTurns - 1) - ed);
// Base case i.e last turn
if (beg == ed) {
// if it is P1's turn
if (turnsTillNow % 2 == 0)
return { money[beg], "L" };
// if P2's turn
else
return { 0, "L" };
}
// Player picks money from
// the left end
pair<int, string> scoreOne
= maxScore(money,
beg + 1,
ed);
// Player picks money from
// the right end
pair<int, string> scoreTwo
= maxScore(money, beg, ed - 1);
if (turnsTillNow % 2 == 0) {
// if it is player 1's turn then
// current picked score added to
// his total. choose maximum of
// the two scores as P1 tries to
// maximize his score.
if (money[beg] + scoreOne.first
> money[ed] + scoreTwo.first) {
return { money[beg] + scoreOne.first,
"L" + scoreOne.second };
}
else
return { money[ed] + scoreTwo.first,
"R" + scoreTwo.second };
}
// if player 2's turn don't add
// current picked bag score to
// total. choose minimum of the
// two scores as P2 tries to
// minimize P1's score.
else {
if (scoreOne.first < scoreTwo.first)
return { scoreOne.first,
"L" + scoreOne.second };
else
return { scoreTwo.first,
"R" + scoreTwo.second };
}
}
// Driver Code
int main()
{
// Input array
int ar[] = { 10, 80, 90, 30 };
int arraySize = sizeof(ar) / sizeof(int);
vector<int> bags(ar, ar + arraySize);
// Function Calling
pair<int, string> ans
= maxScore(bags,
0,
bags.size() - 1);
cout << ans.first << " " << ans.second << endl;
return 0;
}
Java
/*package whatever //do not write package name here */
import java.util.*;
class GFG {
static class Pair<K, V> {
K key;
V value;
public Pair(K first, V second)
{
this.key = first;
this.value = second;
}
}
// Calculates the maximum score
// possible for P1 If only the
// bags from beg to ed were available
static Pair<Integer, String>
maxScore(int []money, int beg, int ed)
{
// Length of the game
int totalTurns = money.length;
// Which turn is being played
int turnsTillNow
= beg + ((totalTurns - 1) - ed);
// Base case i.e last turn
if (beg == ed) {
// if it is P1's turn
if (turnsTillNow % 2 == 0)
return new Pair<Integer, String>(
money[beg], "L");
// if P2's turn
else
return new Pair<Integer, String>(0, "L");
}
// Player picks money from
// the left end
Pair<Integer, String> scoreOne
= maxScore(money, beg + 1, ed);
// Player picks money from
// the right end
Pair<Integer, String> scoreTwo
= maxScore(money, beg, ed - 1);
if (turnsTillNow % 2 == 0) {
// if it is player 1's turn then
// current picked score added to
// his total. choose maximum of
// the two scores as P1 tries to
// maximize his score.
if (money[beg] + scoreOne.key
> money[ed] + scoreTwo.key) {
return new Pair<Integer, String>(money[beg] + scoreOne.key,"L" + scoreOne.value);
}
else
return new Pair<Integer, String>(
money[ed] + scoreTwo.key,
"R" + scoreTwo.value);
}
// if player 2's turn don't add
// current picked bag score to
// total. choose minimum of the
// two scores as P2 tries to
// minimize P1's score.
else {
if (scoreOne.key < scoreTwo.key)
return new Pair<Integer, String>(
scoreOne.key, "L" + scoreOne.value);
else
return new Pair<Integer, String>(
scoreTwo.key + 110,
"R" + scoreTwo.value);
}
}
public static void main(String[] args)
{
int[] ar = { 10, 80, 90, 30 };
int arraySize = ar.length;
int []bags = new int[arraySize];
// Function Calling
Pair<Integer, String> ans
= maxScore(bags, 0, bags.length - 1);
System.out.println(ans.key + " " + ans.value);
}
}
// This code is contributed by aadityaburujwale.
Python3
# Python3 implementation
# Calculates the maximum score
# possible for P1 If only the
# bags from beg to ed were available
def maxScore( money, beg, ed):
# Length of the game
totalTurns = len(money)
# Which turn is being played
turnsTillNow = beg + ((totalTurns - 1) - ed)
# Base case i.e last turn
if (beg == ed):
# if it is P1's turn
if (turnsTillNow % 2 == 0):
return [money[beg], "L"]
# if P2's turn
else:
return [0, "L"]
# Player picks money from
# the left end
scoreOne = maxScore(money, beg + 1, ed)
# Player picks money from
# the right end
scoreTwo = maxScore(money, beg, ed - 1)
if (turnsTillNow % 2 == 0):
# If it is player 1's turn then
# current picked score added to
# his total. choose maximum of
# the two scores as P1 tries to
# maximize his score.
if (money[beg] + scoreOne[0] >
money[ed] + scoreTwo[0]):
return [money[beg] + scoreOne[0],
"L" + scoreOne[1]]
else:
return [money[ed] + scoreTwo[0],
"R" + scoreTwo[1]]
# If player 2's turn don't add
# current picked bag score to
# total. choose minimum of the
# two scores as P2 tries to
# minimize P1's score.
else:
if (scoreOne[0] < scoreTwo[0]):
return[scoreOne[0], "L" + scoreOne[1]]
else:
return[scoreTwo[0], "R" + scoreTwo[1]]
# Driver Code
# Input array
ar = [ 10, 80, 90, 30 ]
arraySize = len(ar)
bags = ar
# Function Calling
ans = maxScore(bags, 0, arraySize - 1)
print(ans[0], ans[1])
# This code is contributed by shivani
C#
// C# implementation
using System;
using System.Collections.Generic;
class GFG {
// Calculates the maximum score
// possible for P1 If only the
// bags from beg to ed were available
static Tuple<int,string> maxScore(List<int> money, int beg, int ed)
{
// Length of the game
int totalTurns = money.Count;
// Which turn is being played
int turnsTillNow = beg + ((totalTurns - 1) - ed);
// Base case i.e last turn
if (beg == ed)
{
// if it is P1's turn
if (turnsTillNow % 2 == 0)
return new Tuple<int,string>(money[beg], "L");
// if P2's turn
else
return new Tuple<int,string>(0, "L");
}
// Player picks money from
// the left end
Tuple<int,string> scoreOne = maxScore(money, beg + 1, ed);
// Player picks money from
// the right end
Tuple<int,string> scoreTwo = maxScore(money, beg, ed - 1);
if (turnsTillNow % 2 == 0)
{
// if it is player 1's turn then
// current picked score added to
// his total. choose maximum of
// the two scores as P1 tries to
// maximize his score.
if (money[beg] + scoreOne.Item1
> money[ed] + scoreTwo.Item1)
{
return new Tuple<int,string>(money[beg] + scoreOne.Item1, "L" + scoreOne.Item2);
}
else
return new Tuple<int,string>(money[ed] + scoreTwo.Item1, "R" + scoreTwo.Item2);
}
// if player 2's turn don't add
// current picked bag score to
// total. choose minimum of the
// two scores as P2 tries to
// minimize P1's score.
else {
if (scoreOne.Item1 < scoreTwo.Item1)
return new Tuple<int,string>(scoreOne.Item1, "L" + scoreOne.Item2);
else
return new Tuple<int,string>(scoreTwo.Item1+110, "R" + scoreTwo.Item2);
}
}
static void Main() {
// Input array
int[] ar = { 10, 80, 90, 30 };
int arraySize = ar.Length;
List<int> bags = new List<int>(new int[arraySize]);
// Function Calling
Tuple<int, string> ans = maxScore(bags, 0, bags.Count - 1);
Console.Write(ans.Item1 + " " + ans.Item2);
}
}
// This code is contributed by suresh07.
JavaScript
<script>
// Javascript implementation
// Calculates the maximum score
// possible for P1 If only the
// bags from beg to ed were available
function maxScore(money, beg, ed)
{
// Length of the game
let totalTurns = money.length;
// Which turn is being played
let turnsTillNow = beg + ((totalTurns - 1) - ed);
// Base case i.e last turn
if (beg == ed)
{
// if it is P1's turn
if (turnsTillNow % 2 == 0)
return [money[beg], "L"];
// if P2's turn
else
return [0, "L"];
}
// Player picks money from
// the left end
let scoreOne = maxScore(money, beg + 1, ed);
// Player picks money from
// the right end
let scoreTwo = maxScore(money, beg, ed - 1);
if (turnsTillNow % 2 == 0)
{
// if it is player 1's turn then
// current picked score added to
// his total. choose maximum of
// the two scores as P1 tries to
// maximize his score.
if (money[beg] + scoreOne[0]
> money[ed] + scoreTwo[0])
{
return [money[beg] + scoreOne[0], "L" + scoreOne[1]];
}
else
return [money[ed] + scoreTwo[[0]], "R" + scoreTwo[1]];
}
// if player 2's turn don't add
// current picked bag score to
// total. choose minimum of the
// two scores as P2 tries to
// minimize P1's score.
else {
if (scoreOne.first < scoreTwo.first)
return [scoreOne[0], "L" + scoreOne[1]];
else
return [scoreTwo[0], "R" + scoreTwo[1]];
}
}
// Driver Code
// Input array
let ar = [10, 80, 90, 30];
let arraySize = ar.length;
let bags = ar;
// Function Calling
let ans = maxScore(bags, 0, bags.length - 1);
document.write(ans[0] + " " + ans[1] + "<br>");
// This code is contributed by gfgking.
</script>
The time complexity of the above approach is exponential.
Optimal Approach:
We can solve this problem by using dynamic programming in O(n^{2}) time and space complexity.
- If we store the best possible answers for all the bags from some beginning i to some ending j then there can be at most n^{2} such different subproblems.
- Let dp(i, j) represent the max score P1 can attain if the only remaining bags in the row start from i and end at j. Then the following hold:
- if it is P1's turn
- dp(i, j) = maximum of score of bag i + dp(i+1, j) or score of bag j + dp(i, j-1).
- if it is P2's turn
- dp(i, j) = minimum of dp(i+1, j) or dp(i, j-1).
Since the current bag's score goes to P2 we don't add it to dp(i, j).
- To keep the track of the moves that take place at a given state we keep an additional boolean matrix which allows us to reconstruct the entire game moves that lead to the maximum score.
- The matrix leftBag(i, j) represents a state in which only the bag from i to j are present. leftBag(i, j) is 1 if it is optimal to pick the leftBag otherwise it is 0.
- The function getMoves uses this matrix to reconstruct the correct moves.
Below is the implementation of the above approach:
C++
// C++ implementation
#include <bits/stdc++.h>
#define maxSize 3000
using namespace std;
// dp(i, j) is the best
// score possible if only
// the bags from i, j were
// present.
int dp[maxSize][maxSize];
// leftBag(i, j) is 1 if in the
// optimal game the player picks
// the leftmost bag when only the
// bags from i to j are present.
bool leftBag[maxSize][maxSize];
// Function to calculate the maximum
// value
int maxScore(vector<int> money)
{
// we will fill the dp table
// in a bottom-up manner. fill
// all states that represent
// lesser number of bags before
// filling states that represent
// higher number of bags.
// we start from states dp(i, i)
// as these are the base case of
// our DP solution.
int n = money.size();
int totalTurns = n;
// turn = 1 if it is player 1's
// turn else 0. Who gets to pick
// the last bag(bottom-up so we
// start from last turn)
bool turn
= (totalTurns % 2 == 0) ? 0 : 1;
// if bag is picked by P1 add it
// to the ans else 0 contribution
// to score.
for (int i = 0; i < n; i++) {
dp[i][i] = turn ? money[i] : 0;
leftBag[i][i] = 1;
}
// 2nd last bag is picked by
// the other player.
turn = !turn;
// sz represents the size
// or number of bags in
// the state dp(i, i+sz)
int sz = 1;
while (sz < n) {
for (int i = 0; i + sz < n; i++) {
int scoreOne = dp[i + 1][i + sz];
int scoreTwo = dp[i][i + sz - 1];
// First player
if (turn) {
dp[i][i + sz]
= max(money[i] + scoreOne,
money[i + sz] + scoreTwo);
// if leftBag has more profit
if (money[i] + scoreOne
> money[i + sz] + scoreTwo)
leftBag[i][i + sz] = 1;
else
leftBag[i][i + sz] = 0;
}
// second player
else {
dp[i][i + sz]
= min(scoreOne,
scoreTwo);
if (scoreOne < scoreTwo)
leftBag[i][i + sz] = 1;
else
leftBag[i][i + sz] = 0;
}
}
// Give turn to the
// other player.
turn = !turn;
// Now fill states
// with more bags.
sz++;
}
return dp[0][n - 1];
}
// Using the leftBag matrix,
// generate the actual game
// moves that lead to the score.
string getMoves(int n)
{
string moves;
int left = 0, right = n - 1;
while (left <= right) {
// if the bag is picked from left
if (leftBag[left][right]) {
moves.push_back('L');
left++;
}
else {
moves.push_back('R');
right--;
}
}
return moves;
}
// Driver Code
int main()
{
int ar[] = { 10, 80, 90, 30 };
int arraySize = sizeof(ar) / sizeof(int);
vector<int> bags(ar, ar + arraySize);
int ans = maxScore(bags);
cout << ans << " " << getMoves(bags.size());
return 0;
}
Java
// Java Implementation
public class Main
{
static int maxSize = 3000;
// dp(i, j) is the best
// score possible if only
// the bags from i, j were
// present.
static int[][] dp = new int[maxSize][maxSize];
// leftBag(i, j) is 1 if in the
// optimal game the player picks
// the leftmost bag when only the
// bags from i to j are present.
static boolean[][] leftBag = new boolean[maxSize][maxSize];
// Function to calculate the maximum
// value
static int maxScore(int[] money)
{
// we will fill the dp table
// in a bottom-up manner. fill
// all states that represent
// lesser number of bags before
// filling states that represent
// higher number of bags.
// we start from states dp(i, i)
// as these are the base case of
// our DP solution.
int n = money.length;
int totalTurns = n;
// turn = 1 if it is player 1's
// turn else 0. Who gets to pick
// the last bag(bottom-up so we
// start from last turn)
boolean turn = (totalTurns % 2 == 0) ? false : true;
// if bag is picked by P1 add it
// to the ans else 0 contribution
// to score.
for (int i = 0; i < n; i++) {
dp[i][i] = turn ? money[i] : 0;
leftBag[i][i] = true;
}
// 2nd last bag is picked by
// the other player.
turn = !turn;
// sz represents the size
// or number of bags in
// the state dp(i, i+sz)
int sz = 1;
while (sz < n) {
for (int i = 0; i + sz < n; i++) {
int scoreOne = dp[i + 1][i + sz];
int scoreTwo = dp[i][i + sz - 1];
// First player
if (turn) {
dp[i][i + sz] = Math.max(money[i] + scoreOne, money[i + sz] + scoreTwo);
// if leftBag has more profit
if (money[i] + scoreOne > money[i + sz] + scoreTwo)
leftBag[i][i + sz] = true;
else
leftBag[i][i + sz] = false;
}
// second player
else {
dp[i][i + sz] = Math.min(scoreOne, scoreTwo);
if (scoreOne < scoreTwo)
leftBag[i][i + sz] = true;
else
leftBag[i][i + sz] = false;
}
}
// Give turn to the
// other player.
turn = !turn;
// Now fill states
// with more bags.
sz++;
}
return dp[0][n - 1];
}
// Using the leftBag matrix,
// generate the actual game
// moves that lead to the score.
static String getMoves(int n)
{
String moves = "";
int left = 0, right = n - 1;
while (left <= right) {
// if the bag is picked from left
if (leftBag[left][right]) {
moves = moves + 'L';
left++;
}
else {
moves = moves + 'R';
right--;
}
}
return moves;
}
public static void main(String[] args) {
for(int i = 0; i < maxSize; i++)
{
for(int j = 0; j < maxSize; j++)
{
dp[i][j] = 0;
leftBag[i][j] = false;
}
}
int[] ar = { 10, 80, 90, 30 };
int arraySize = ar.length;
int[] bags = ar;
int ans = maxScore(bags);
System.out.print(ans + " " + getMoves(bags.length));
}
}
// This code is contributed by divyes072019.
Python3
# Python3 Implementation
maxSize = 3000
# dp(i, j) is the best
# score possible if only
# the bags from i, j were
# present.
dp = [[0 for i in range(maxSize)] for j in range(maxSize)]
# leftBag(i, j) is 1 if in the
# optimal game the player picks
# the leftmost bag when only the
# bags from i to j are present.
leftBag = [[False for i in range(maxSize)] for j in range(maxSize)]
# Function to calculate the maximum
# value
def maxScore(money):
# we will fill the dp table
# in a bottom-up manner. fill
# all states that represent
# lesser number of bags before
# filling states that represent
# higher number of bags.
# we start from states dp(i, i)
# as these are the base case of
# our DP solution.
n = len(money)
totalTurns = n
# turn = 1 if it is player 1's
# turn else 0. Who gets to pick
# the last bag(bottom-up so we
# start from last turn)
turn = 0 if (totalTurns % 2 == 0) else 1
# if bag is picked by P1 add it
# to the ans else 0 contribution
# to score.
for i in range(n):
dp[i][i] = money[i] if turn else 0
leftBag[i][i] = 1
# 2nd last bag is picked by
# the other player.
turn = not turn
# sz represents the size
# or number of bags in
# the state dp(i, i+sz)
sz = 1
while sz < n:
i = 0
while i + sz < n:
scoreOne = dp[i + 1][i + sz]
scoreTwo = dp[i][i + sz - 1]
# First player
if turn:
dp[i][i + sz] = max(money[i] + scoreOne, money[i + sz] + scoreTwo)
# if leftBag has more profit
if (money[i] + scoreOne > money[i + sz] + scoreTwo):
leftBag[i][i + sz] = 1
else:
leftBag[i][i + sz] = 0
# second player
else:
dp[i][i + sz] = min(scoreOne, scoreTwo)
if (scoreOne < scoreTwo):
leftBag[i][i + sz] = 1
else:
leftBag[i][i + sz] = 0
i += 1
# Give turn to the
# other player.
turn = not turn
# Now fill states
# with more bags.
sz += 1
return dp[0][n - 1]
# Using the leftBag matrix,
# generate the actual game
# moves that lead to the score.
def getMoves(n):
moves = ""
left, right = 0, n - 1
while (left <= right):
# if the bag is picked from left
if (leftBag[left][right]):
moves = moves + 'L'
left += 1
else:
moves = moves + 'R'
right -= 1
return moves
ar = [ 10, 80, 90, 30 ]
arraySize = len(ar)
bags = ar
ans = maxScore(bags)
print(ans, getMoves(len(bags)), sep=" ")
# This code is contributed by mukesh07.
C#
// C# Implementation
using System;
class GFG {
static int maxSize = 3000;
// dp(i, j) is the best
// score possible if only
// the bags from i, j were
// present.
static int[,] dp = new int[maxSize, maxSize];
// leftBag(i, j) is 1 if in the
// optimal game the player picks
// the leftmost bag when only the
// bags from i to j are present.
static bool[,] leftBag = new bool[maxSize, maxSize];
// Function to calculate the maximum
// value
static int maxScore(int[] money)
{
// we will fill the dp table
// in a bottom-up manner. fill
// all states that represent
// lesser number of bags before
// filling states that represent
// higher number of bags.
// we start from states dp(i, i)
// as these are the base case of
// our DP solution.
int n = money.Length;
int totalTurns = n;
// turn = 1 if it is player 1's
// turn else 0. Who gets to pick
// the last bag(bottom-up so we
// start from last turn)
bool turn = (totalTurns % 2 == 0) ? false : true;
// if bag is picked by P1 add it
// to the ans else 0 contribution
// to score.
for (int i = 0; i < n; i++) {
dp[i,i] = turn ? money[i] : 0;
leftBag[i,i] = true;
}
// 2nd last bag is picked by
// the other player.
turn = !turn;
// sz represents the size
// or number of bags in
// the state dp(i, i+sz)
int sz = 1;
while (sz < n) {
for (int i = 0; i + sz < n; i++) {
int scoreOne = dp[i + 1,i + sz];
int scoreTwo = dp[i,i + sz - 1];
// First player
if (turn) {
dp[i,i + sz] = Math.Max(money[i] + scoreOne, money[i + sz] + scoreTwo);
// if leftBag has more profit
if (money[i] + scoreOne > money[i + sz] + scoreTwo)
leftBag[i,i + sz] = true;
else
leftBag[i,i + sz] = false;
}
// second player
else {
dp[i,i + sz] = Math.Min(scoreOne, scoreTwo);
if (scoreOne < scoreTwo)
leftBag[i, i + sz] = true;
else
leftBag[i, i + sz] = false;
}
}
// Give turn to the
// other player.
turn = !turn;
// Now fill states
// with more bags.
sz++;
}
return dp[0,n - 1];
}
// Using the leftBag matrix,
// generate the actual game
// moves that lead to the score.
static string getMoves(int n)
{
string moves = "";
int left = 0, right = n - 1;
while (left <= right) {
// if the bag is picked from left
if (leftBag[left,right]) {
moves = moves + 'L';
left++;
}
else {
moves = moves + 'R';
right--;
}
}
return moves;
}
static void Main()
{
for(int i = 0; i < maxSize; i++)
{
for(int j = 0; j < maxSize; j++)
{
dp[i,j] = 0;
leftBag[i,j] = false;
}
}
int[] ar = { 10, 80, 90, 30 };
int arraySize = ar.Length;
int[] bags = ar;
int ans = maxScore(bags);
Console.Write(ans + " " + getMoves(bags.Length));
}
}
// This code is contributed by decode2207.
JavaScript
<script>
// Javascript Implementation
let maxSize = 3000;
// dp(i, j) is the best
// score possible if only
// the bags from i, j were
// present.
let dp = new Array(maxSize);
for(let i = 0; i < maxSize; i++)
{
dp[i] = new Array(maxSize);
for(let j = 0; j < maxSize; j++)
{
dp[i][j] = 0;
}
}
// leftBag(i, j) is 1 if in the
// optimal game the player picks
// the leftmost bag when only the
// bags from i to j are present.
let leftBag = new Array(maxSize);
for(let i = 0; i < maxSize; i++)
{
leftBag[i] = new Array(maxSize);
for(let j = 0; j < maxSize; j++)
{
leftBag[i][j] = false;
}
}
// Function to calculate the maximum
// value
function maxScore(money)
{
// we will fill the dp table
// in a bottom-up manner. fill
// all states that represent
// lesser number of bags before
// filling states that represent
// higher number of bags.
// we start from states dp(i, i)
// as these are the base case of
// our DP solution.
let n = money.length;
let totalTurns = n;
// turn = 1 if it is player 1's
// turn else 0. Who gets to pick
// the last bag(bottom-up so we
// start from last turn)
let turn = (totalTurns % 2 == 0) ? 0 : 1;
// if bag is picked by P1 add it
// to the ans else 0 contribution
// to score.
for (let i = 0; i < n; i++) {
dp[i][i] = turn ? money[i] : 0;
leftBag[i][i] = 1;
}
// 2nd last bag is picked by
// the other player.
turn = !turn;
// sz represents the size
// or number of bags in
// the state dp(i, i+sz)
let sz = 1;
while (sz < n) {
for (let i = 0; i + sz < n; i++) {
let scoreOne = dp[i + 1][i + sz];
let scoreTwo = dp[i][i + sz - 1];
// First player
if (turn) {
dp[i][i + sz]
= Math.max(money[i] + scoreOne,
money[i + sz] + scoreTwo);
// if leftBag has more profit
if (money[i] + scoreOne
> money[i + sz] + scoreTwo)
leftBag[i][i + sz] = 1;
else
leftBag[i][i + sz] = 0;
}
// second player
else {
dp[i][i + sz]
= Math.min(scoreOne,
scoreTwo);
if (scoreOne < scoreTwo)
leftBag[i][i + sz] = 1;
else
leftBag[i][i + sz] = 0;
}
}
// Give turn to the
// other player.
turn = !turn;
// Now fill states
// with more bags.
sz++;
}
return dp[0][n - 1];
}
// Using the leftBag matrix,
// generate the actual game
// moves that lead to the score.
function getMoves(n)
{
let moves = "";
let left = 0, right = n - 1;
while (left <= right) {
// if the bag is picked from left
if (leftBag[left][right]) {
moves = moves + 'L';
left++;
}
else {
moves = moves + 'R';
right--;
}
}
return moves;
}
let ar = [ 10, 80, 90, 30 ];
let arraySize = ar.length;
let bags = ar;
let ans = maxScore(bags);
document.write(ans + " " + getMoves(bags.length));
// This code is contributed by divyeshrabadiya07.
</script>
Time and space complexities of this approach are O(N^{2}) .
Similar Reads
Basics & Prerequisites
Data Structures
Array Data StructureIn this article, we introduce array, implementation in different popular languages, its basic operations and commonly seen problems / interview questions. An array stores items (in case of C/C++ and Java Primitive Arrays) or their references (in case of Python, JS, Java Non-Primitive) at contiguous
3 min read
String in Data StructureA string is a sequence of characters. The following facts make string an interesting data structure.Small set of elements. Unlike normal array, strings typically have smaller set of items. For example, lowercase English alphabet has only 26 characters. ASCII has only 256 characters.Strings are immut
2 min read
Hashing in Data StructureHashing is a technique used in data structures that efficiently stores and retrieves data in a way that allows for quick access. Hashing involves mapping data to a specific index in a hash table (an array of items) using a hash function. It enables fast retrieval of information based on its key. The
2 min read
Linked List Data StructureA linked list is a fundamental data structure in computer science. It mainly allows efficient insertion and deletion operations compared to arrays. Like arrays, it is also used to implement other data structures like stack, queue and deque. Hereâs the comparison of Linked List vs Arrays Linked List:
2 min read
Stack Data StructureA Stack is a linear data structure that follows a particular order in which the operations are performed. The order may be LIFO(Last In First Out) or FILO(First In Last Out). LIFO implies that the element that is inserted last, comes out first and FILO implies that the element that is inserted first
2 min read
Queue Data StructureA Queue Data Structure is a fundamental concept in computer science used for storing and managing data in a specific order. It follows the principle of "First in, First out" (FIFO), where the first element added to the queue is the first one to be removed. It is used as a buffer in computer systems
2 min read
Tree Data StructureTree Data Structure is a non-linear data structure in which a collection of elements known as nodes are connected to each other via edges such that there exists exactly one path between any two nodes. Types of TreeBinary Tree : Every node has at most two childrenTernary Tree : Every node has at most
4 min read
Graph Data StructureGraph Data Structure is a collection of nodes connected by edges. It's used to represent relationships between different entities. If you are looking for topic-wise list of problems on different topics like DFS, BFS, Topological Sort, Shortest Path, etc., please refer to Graph Algorithms. Basics of
3 min read
Trie Data StructureThe Trie data structure is a tree-like structure used for storing a dynamic set of strings. It allows for efficient retrieval and storage of keys, making it highly effective in handling large datasets. Trie supports operations such as insertion, search, deletion of keys, and prefix searches. In this
15+ min read
Algorithms
Searching AlgorithmsSearching algorithms are essential tools in computer science used to locate specific items within a collection of data. In this tutorial, we are mainly going to focus upon searching in an array. When we search an item in an array, there are two most common algorithms used based on the type of input
2 min read
Sorting AlgorithmsA Sorting Algorithm is used to rearrange a given array or list of elements in an order. For example, a given array [10, 20, 5, 2] becomes [2, 5, 10, 20] after sorting in increasing order and becomes [20, 10, 5, 2] after sorting in decreasing order. There exist different sorting algorithms for differ
3 min read
Introduction to RecursionThe process in which a function calls itself directly or indirectly is called recursion and the corresponding function is called a recursive function. A recursive algorithm takes one step toward solution and then recursively call itself to further move. The algorithm stops once we reach the solution
14 min read
Greedy AlgorithmsGreedy algorithms are a class of algorithms that make locally optimal choices at each step with the hope of finding a global optimum solution. At every step of the algorithm, we make a choice that looks the best at the moment. To make the choice, we sometimes sort the array so that we can always get
3 min read
Graph AlgorithmsGraph is a non-linear data structure like tree data structure. The limitation of tree is, it can only represent hierarchical data. For situations where nodes or vertices are randomly connected with each other other, we use Graph. Example situations where we use graph data structure are, a social net
3 min read
Dynamic Programming or DPDynamic Programming is an algorithmic technique with the following properties.It is mainly an optimization over plain recursion. Wherever we see a recursive solution that has repeated calls for the same inputs, we can optimize it using Dynamic Programming. The idea is to simply store the results of
3 min read
Bitwise AlgorithmsBitwise algorithms in Data Structures and Algorithms (DSA) involve manipulating individual bits of binary representations of numbers to perform operations efficiently. These algorithms utilize bitwise operators like AND, OR, XOR, NOT, Left Shift, and Right Shift.BasicsIntroduction to Bitwise Algorit
4 min read
Advanced
Segment TreeSegment Tree is a data structure that allows efficient querying and updating of intervals or segments of an array. It is particularly useful for problems involving range queries, such as finding the sum, minimum, maximum, or any other operation over a specific range of elements in an array. The tree
3 min read
Pattern SearchingPattern searching algorithms are essential tools in computer science and data processing. These algorithms are designed to efficiently find a particular pattern within a larger set of data. Patten SearchingImportant Pattern Searching Algorithms:Naive String Matching : A Simple Algorithm that works i
2 min read
GeometryGeometry is a branch of mathematics that studies the properties, measurements, and relationships of points, lines, angles, surfaces, and solids. From basic lines and angles to complex structures, it helps us understand the world around us.Geometry for Students and BeginnersThis section covers key br
2 min read
Interview Preparation
Practice Problem