Player with max score | Practice | GeeksforGeeks

Given an array arr of non-negative integers of size N, 2 players are playing a game. In each move, a player chooses an element from either end of the array, and the size of the array shrinks by one. Both players take alternate chances and the game continues until the size of the array becomes 0. Every time a player chooses an array element the array value is added to the player's score. At the end player with maximum score wins.
If player 1 starts the game, you have to predict whether player 1 will win the game or not. Both players will play optimally.
 
Example 1:
Input:
N = 3
arr[] = {2,6,3}
Output:
0 
Explanation:
Initially, player 1 can choose between 2 and 3. 
If he chooses 3 (or 2), then player 2 can choose 
from 2 (or 3) and 6. If player 2 chooses 6,
then player 1 will be left with 2 (or 3). 
So, final score of player 1 is 2 + 3 = 5,
and player 2 is 6. 
Hence, player 1 will never be the winner and 
output is 0.

Your Task:  
You don't need to read input or print anything. Your task is to complete the function is1winner() which takes the array arr[], its size N and returns true if player 1 is the winner and false otherwise.
The driver code itself prints 1 if returned value is true and 0 otherwise.

Expected Time Complexity: O(N*N)
Expected Auxiliary Space: O(N)

Constraints:
1 <= N <= 1000
0<= arr[i] <= 105
0
prajjwalfire3 weeks ago
  int help(vector<int>& prefix,int lo,int hi,int arr[],vector<vector<int>>& dp)
  {
      if(hi-lo+1==1)
         return arr[lo];
         
      if(dp[lo][hi]!=-1)
          return dp[lo][hi];
      
      int total=prefix[hi]-prefix[lo]+arr[lo];
      
      int one=total-help(prefix,lo+1,hi,arr,dp)
      
      int sec=total-help(prefix,lo,hi-1,arr,dp);
      
      return dp[lo][hi]=max(one,sec);   
  }
    bool is1winner(int N,int arr[]) {

       vector<vector<int>> dp(N,vector<int>(N,-1));
        
        vector<int> prefix(N);
        
        prefix[0]=arr[0];
        
        for(int i=1;i<N;i++)
        {
            prefix[i]=prefix[i-1]+arr[i];
        }
        
        auto player_one_score=help(prefix,0,N-1,arr,dp);
 
        int total=prefix.back();
        
        return player_one_score>total-player_one_score;   
    }
0
hamidnourashraf1 month ago
class Solution:
    
    def rec_pick(self, arr, i, j, mem):
        if i > j:
            return 0
        if mem[i][j] != -1:
            return mem[i][j]
            
        case1 = arr[i] + min(self.rec_pick(arr, i+2, j, mem), self.rec_pick(arr, i+1, j-1, mem))
        case2 = arr[j] + min(self.rec_pick(arr, i, j-2, mem), self.rec_pick(arr, i+1, j-1, mem))
        mem[i][j] = max(case1, case2)
        return mem[i][j]
   
    def is1winner (self, N, arr):
        mem = [[-1] * N for i in range(N)]
        p1 = self.rec_pick(arr, 0, N-1, mem)
        if p1 > (sum(arr) - p1):
            return True
        return False
0
pj63371 month ago
Why wont the greedy solution work?
+1
abhishekguptaaa3 months ago
OPTIMAL STRATEGY FOR A GAME TOP DOWN APPROACH:
class Solution{   public:
  int dp[1002][1002];      int solve(int i, int j, int arr[])  {      if(i>j)      {          return 0;      }      if(dp[i][j]!=-1)      {          return dp[i][j];      }            int x=arr[i]+min(solve(i+2,j,arr),solve(i+1,j-1,arr));      int y=arr[j]+min(solve(i+1,j-1,arr),solve(i,j-2,arr));            return dp[i][j]=max(x,y);  } 
   bool is1winner(int N,int arr[]) {              // code here              dp[N][N];              memset(dp,-1,sizeof(dp));              int sum=0;       for(int i=0;i<N;i++)       {                      sum+=arr[i];                  }              int res=solve(0,N-1,arr);              if(res>(sum-res))       {           return true;       }       else       {           return false;       }                 }
0
2001shivank4 months ago
4 test cases, N=396,47,1000,100 there was some issue with my code. can someone explain? 
+17
rainx6 months ago
EXPLAINATION
As a respectable player1 , our task is to make player2 have the taste of defeat, Now how we gonna make it sure. Of-course, when will dynamic chance help us. Since the question says both player play optimally, we will write code so to make sure player1 our friend wins the game.
 
Now, lets think how can our friend win against the opponent. I think if we can beforehand know, if the array element we are picking can help us in making sure the opponent always gets the minimum number, so we used our mind and write the recurrence function based on this idea. Let's see some cases to make our dumb friend clear.
 
CASE 1:  PICK FROM FRONT
So Mr.Player1, if you pick from front, its fine, put the front element number in your bag and now, recursively make sure that the next number your opponent gets is minimum, So now the enemy will have two choice if you pick the first element, he will either pick the last element OR will pick the now front element and we want this kid to have the least possible value for himself. So we will take the minimum of the two.
 
CASE 2: PICK FROM END 
So Mr.Player1, if you pick from END, its fine, put the end element number in your bag and now, recursively make sure that the next number your opponent gets is minimum, So now the enemy will have two choice ,if you pick the end element, he will either pick the now last element OR will pick the front element and we want this kid to have the least possible value for himself. So we will take the minimum of the two.
 
Now, after we are done, we will save the maximum of two choices as obviously player1 will choose the max of the two choices.
So player1 will choose
max(CHOICE1 , CHOICE2).
SO, THE RECURRENCE RELATION BOILS DOWN TO----
 
Choice1=arr[front]+min(func(arr,start+2,end),func(arr,start+1,end-1);
 
Choice2=arr[end]+min(func(arr,start+1,end-1),func(arr,start,end-2);
 
return max(Choice1,Choice2);
 
 
CODE IMPLEMENTATION IS DOWN BELOW-
 
int dp[1001][1001];

int helper(int arr[], int start, int end){
    if(start>end){
       return dp[start][end]=0;
    }
    if(start==end){
       return dp[start][end]=arr[end];
    }
    if(dp[start][end]!=-1){
       return dp[start][end];
    }
    
    int firstPick=arr[start]+min(helper(arr,start+2,end),helper(arr,start+1,end-1));
    
    int endPick=arr[end]+min(helper(arr,start,end-2),helper(arr,start+1,end-1));
    
   return dp[start][end]=max(firstPick,endPick);
}

bool is1winner(int N,int arr[]){
        memset(dp,-1,sizeof(dp));
        int sum=0;
        for(int i=0;i<N;i++){
            sum+=arr[i];
        }
        int player1=helper(arr,0,N-1);
        int player2=sum-player1;
        return player1>player2;
}
 
Upvote if you like and happy coding
-1
chirags_307 months ago
class Solution{   
public:
    int dp[1001][1001];
    int solve(int arr[], int s, int e)
    {
        if(s == e) return arr[s];
        
        if(dp[s][e] != -1)
            return dp[s][e];
        
        return dp[s][e] = max(arr[s] - solve(arr, s+1, e), arr[e] - solve(arr, s, e-1));
    }
    
    bool is1winner(int N,int arr[]) {
        // code here
        memset(dp, -1, sizeof(dp));
        return solve(arr, 0, N-1) > 0;
    }
};
0
Mike8 months ago
Mike
ACCECPTED!!https://uploads.disquscdn.c... D
0
Vikas079 months ago
Vikas07
int dp[1002][1002];class Solution{  public:int solve(int arr[],int i,int j,bool isPlayer1){    if(i>j) return 0;    if(dp[i][j]!=-1) return dp[i][j];    if(isPlayer1){//his job is to maximize the sum    return dp[i][j]= max(arr[i]+solve(arr,i+1,j,0),arr[j]+solve(arr,i,j-1,0));        }        else {            return dp[i][j]= min(arr[i]*(-1)+solve(arr,i+1,j,1),arr[j]*(-1)+solve(arr,i,j-1,1));        }
}    bool is1winner(int N,int arr[]) {        memset(dp,-1,sizeof(dp));       return (solve(arr,0,N-1,1)>0 ? true:false);    }};
0
Vikas079 months ago
Vikas07
This question can be solved using Minimax Algorithm.Add values for player1 and for player2 take arr[i] as arr[i]*(-1) in addition.at last check if addition is negative or positive... thats where the ans lies.
We strongly recommend solving this problem on your own before viewing its editorial. Do you still
                    want to view the editorial?
 Login to access your submissions. 

Problem


Contest

Reset the IDE using the second button on the top right corner.
Avoid using static/global variables in your code as your code is tested against multiple test cases and these tend to retain their previous values.
Passing the Sample/Custom Test cases does not guarantee the correctness of code. On submission, your code is tested against multiple test cases consisting of all possible corner cases and stress constraints.
You can access the hints to get an idea about what is expected of you as well as the final solution code.
You can view the solutions submitted by other users from the submission tab.