Maximum score possible after performing given operations on an Array

Given an array A of size N, the task is to find the maximum score possible of this array. The score of an array is calculated by performing the following operations on the array N times:Â
- If the operation is odd-numbered, the score is incremented by the sum of all elements of the current array.
 - If the operation is even-numbered, the score is decremented by the sum of all elements of the current array.Â
 - After every operation, either remove the first or the last element of the remaining array.Â
Â
Examples:Â
Input: A = {1, 2, 3, 4, 2, 6}Â
Output: 13Â
Explanation:Â
The optimal operations are:Â
1. Operation 1 is odd.Â
-> So add the sum of the array to the score: Score = 0 + 18 = 18Â
-> remove 6 from last,Â
-> new array A = [1, 2, 3, 4, 2]Â
2. Operation 2 is even.Â
-> So subtract the sum of the array from the score: Score = 18 – 12 = 6Â
-> remove 2 from last,Â
-> new array A = [1, 2, 3, 4]Â
3. Operation 1 is odd.Â
-> So add the sum of the array to the score: Score = 6 + 10 = 16Â
-> remove 4 from last,Â
-> new array A = [1, 2, 3]Â
4. Operation 4 is even.Â
-> So subtract the sum of the array from the score: Score = 16 – 6 = 10Â
-> remove 1 from start,Â
-> new array A = [2, 3]Â
5. Operation 5 is odd.Â
-> So add the sum of the array to the score: Score = 10 + 5 = 15Â
-> remove 3 from last,Â
-> new array A = [2]Â
6. Operation 6 is even.Â
-> So subtract the sum of the array from the score: Score = 15 – 2 = 13Â
-> remove 2 from first,Â
-> new array A = []Â
The array is empty so no further operations are possible.Input: A = [5, 2, 2, 8, 1, 16, 7, 9, 12, 4]Â
Output: 50Â
Naive approachÂ
Â
- In each operation, we have to remove either the leftmost or the rightmost element. A simple way would be to consider all possible ways to remove elements and for each branch compute the score and find the maximum score out of all. This can simply be done using recursion.Â
 - The information we need to keep in each step would beÂ
- The remaining array [l, r], where l represents the leftmost index and r the rightmost,
- The operation number, and
- The current score.
- In order to calculate the sum of any array from [l, r] in each recursive step optimally, we will keep a prefix sum array.Â
Using prefix sum array, new sum from [l, r] can be calculated in O(1) as:Â
Â
Sum(l, r) = prefix_sum[r] – prefix_sum[l-1]Â
Â
Below is the implementation of the above approach:Â
Â
C++
// C++ program to find the maximum// score after given operationsÂ
#include <bits/stdc++.h>using namespace std;Â
// Function to calculate// maximum score recursivelyint maxScore(    int l, int r,    int prefix_sum[],    int num){Â
    // Base case    if (l > r)        return 0;Â
    // Sum of array in range (l, r)    int current_sum        = prefix_sum[r]          - (l - 1 >= 0                 ? prefix_sum[l - 1]                 : 0);Â
    // If the operation is even-numbered    // the score is decremented    if (num % 2 == 0)        current_sum *= -1;Â
    // Exploring all paths, by removing    // leftmost and rightmost element    // and selecting the maximum value    return current_sum           + max(                 maxScore(                     l + 1, r,                     prefix_sum,                     num + 1),                 maxScore(                     l, r - 1,                     prefix_sum,                     num + 1));}Â
// Function to find the max scoreint findMaxScore(int a[], int n){    // Prefix sum array    int prefix_sum[n] = { 0 };Â
    prefix_sum[0] = a[0];Â
    // Calculating prefix_sum    for (int i = 1; i < n; i++) {        prefix_sum[i]            = prefix_sum[i - 1] + a[i];    }Â
    return maxScore(0, n - 1,                    prefix_sum, 1);}Â
// Driver codeint main(){Â Â Â Â int n = 6;Â Â Â Â int A[n] = { 1, 2, 3, 4, 2, 6 };Â
    cout << findMaxScore(A, n);    return 0;} |
Java
// Java program to find the maximum// score after given operationsimport java.util.*;Â
class GFG{Â
// Function to calculate// maximum score recursivelystatic int maxScore(    int l, int r,    int prefix_sum[],    int num){Â
    // Base case    if (l > r)        return 0;Â
    // Sum of array in range (l, r)    int current_sum        = prefix_sum[r]        - (l - 1 >= 0                ? prefix_sum[l - 1]                : 0);Â
    // If the operation is even-numbered    // the score is decremented    if (num % 2 == 0)        current_sum *= -1;Â
    // Exploring all paths, by removing    // leftmost and rightmost element    // and selecting the maximum value    return current_sum        + Math.max(maxScore(l + 1, r,                            prefix_sum,                            num + 1),                    maxScore(l, r - 1,                            prefix_sum,                            num + 1));}Â
// Function to find the max scorestatic int findMaxScore(int a[], int n){    // Prefix sum array    int prefix_sum[] = new int[n];Â
    prefix_sum[0] = a[0];Â
    // Calculating prefix_sum    for (int i = 1; i < n; i++) {        prefix_sum[i]            = prefix_sum[i - 1] + a[i];    }Â
    return maxScore(0, n - 1,                    prefix_sum, 1);}Â
// Driver codepublic static void main(String[] args){Â Â Â Â int n = 6;Â Â Â Â int A[] = { 1, 2, 3, 4, 2, 6 };Â
    System.out.print(findMaxScore(A, n));}}Â
// This code is contributed by sapnasingh4991 |
Python3
# Python3 program to find the maximum# score after given operationsÂ
# Function to calculate maximum# score recursivelydef maxScore(l, r, prefix_sum, num):         # Base case    if (l > r):        return 0;Â
    # Sum of array in range (l, r)    if((l - 1) >= 0):        current_sum = (prefix_sum[r] -                       prefix_sum[l - 1])    else:        current_sum = prefix_sum[r] - 0         # If the operation is even-numbered    # the score is decremented    if (num % 2 == 0):        current_sum *= -1;Â
    # Exploring all paths, by removing    # leftmost and rightmost element    # and selecting the maximum value    return current_sum + max(maxScore(l + 1, r,                                       prefix_sum,                                      num + 1),                             maxScore(l, r - 1,                                       prefix_sum,                                       num + 1));Â
# Function to find the max scoredef findMaxScore(a, n):Â
    # Prefix sum array    prefix_sum = [0] * nÂ
    prefix_sum[0] = a[0]Â
    # Calculating prefix_sum    for i in range(1, n):        prefix_sum[i] = prefix_sum[i - 1] + a[i];             return maxScore(0, n - 1, prefix_sum, 1);Â
# Driver coden = 6;A = [ 1, 2, 3, 4, 2, 6 ]ans = findMaxScore(A, n)Â
print(ans)Â
# This code is contributed by SoumikMondal |
C#
// C# program to find the maximum// score after given operationsusing System;Â
class GFG{  // Function to calculate// maximum score recursivelystatic int maxScore(    int l, int r,    int []prefix_sum,    int num){      // Base case    if (l > r)        return 0;      // Sum of array in range (l, r)    int current_sum        = prefix_sum[r]        - (l - 1 >= 0                ? prefix_sum[l - 1]                : 0);      // If the operation is even-numbered    // the score is decremented    if (num % 2 == 0)        current_sum *= -1;      // Exploring all paths, by removing    // leftmost and rightmost element    // and selecting the maximum value    return current_sum        + Math.Max(maxScore(l + 1, r,                            prefix_sum,                            num + 1),                    maxScore(l, r - 1,                            prefix_sum,                            num + 1));}  // Function to find the max scorestatic int findMaxScore(int []a, int n){    // Prefix sum array    int []prefix_sum = new int[n];      prefix_sum[0] = a[0];      // Calculating prefix_sum    for (int i = 1; i < n; i++) {        prefix_sum[i]            = prefix_sum[i - 1] + a[i];    }      return maxScore(0, n - 1,                    prefix_sum, 1);}  // Driver codepublic static void Main(String[] args){    int n = 6;    int []A = { 1, 2, 3, 4, 2, 6 };      Console.Write(findMaxScore(A, n));}}Â
// This code is contributed by 29AjayKumar |
Javascript
<script>Â
// JavaScript program to find the maximum// score after given operationsÂ
// Function to calculate// maximum score recursivelyfunction maxScore(l, r, prefix_sum, num){Â
    // Base case    if (l > r)        return 0;Â
    // Sum of array in range (l, r)    let current_sum        = prefix_sum[r]        - (l - 1 >= 0                ? prefix_sum[l - 1]                : 0);Â
    // If the operation is even-numbered    // the score is decremented    if (num % 2 == 0)        current_sum *= -1;Â
    // Exploring all paths, by removing    // leftmost and rightmost element    // and selecting the maximum value    return current_sum        + Math.max(                maxScore(                    l + 1, r,                    prefix_sum,                    num + 1),                maxScore(                    l, r - 1,                    prefix_sum,                    num + 1));}Â
// Function to find the max scorefunction findMaxScore(a, n){    // Prefix sum array    let prefix_sum = new Uint8Array(n);Â
    prefix_sum[0] = a[0];Â
    // Calculating prefix_sum    for (let i = 1; i < n; i++) {        prefix_sum[i]            = prefix_sum[i - 1] + a[i];    }Â
    return maxScore(0, n - 1,                    prefix_sum, 1);}Â
// Driver codeÂ
    let n = 6;    let A = [ 1, 2, 3, 4, 2, 6 ];Â
    document.write(findMaxScore(A, n));Â
Â
// This code is contributed by Surbhi Tyagi.Â
</script> |
13
Time complexity: O(2N)
Auxiliary space: O(N)
Efficient approachÂ
Â
- In the previous approach it can be observed that we are calculating same subproblems many times, i.e. it follows the property of Overlapping Subproblems. So we can use Dynamic programming to solve the problemÂ
 - In the recursive solution stated above, we only need to add memoization using a dp table. The states will be:Â
Â
DP table states = dp[l][r][num]
where l and r represent the endpoints of the current array and num represents the operation number.Â
Â
Below is the implementation of the Memoization approach of the recursive code:Â
Â
C++
// C++ program to find the maximum// Score after given operationsÂ
#include <bits/stdc++.h>using namespace std;Â
// Memoizing by the use of a tableint dp[100][100][100];Â
// Function to calculate maximum scoreint MaximumScoreDP(int l, int r,                   int prefix_sum[],                   int num){    // Bse case    if (l > r)        return 0;Â
    // If the same state has    // already been computed    if (dp[l][r][num] != -1)        return dp[l][r][num];Â
    // Sum of array in range (l, r)    int current_sum        = prefix_sum[r]          - (l - 1 >= 0                 ? prefix_sum[l - 1]                 : 0);Â
    // If the operation is even-numbered    // the score is decremented    if (num % 2 == 0)        current_sum *= -1;Â
    // Exploring all paths, and storing    // maximum value in DP table to avoid    // further repetitive recursive calls    dp[l][r][num] = current_sum                    + max(                          MaximumScoreDP(                              l + 1, r,                              prefix_sum,                              num + 1),                          MaximumScoreDP(                              l, r - 1,                              prefix_sum,                              num + 1));Â
    return dp[l][r][num];}Â
// Function to find the max scoreint findMaxScore(int a[], int n){    // Prefix sum array    int prefix_sum[n] = { 0 };Â
    prefix_sum[0] = a[0];Â
    // Calculating prefix_sum    for (int i = 1; i < n; i++) {        prefix_sum[i]            = prefix_sum[i - 1] + a[i];    }Â
    // Initialising the DP table,    // -1 represents the subproblem    // hasn't been solved yet    memset(dp, -1, sizeof(dp));Â
    return MaximumScoreDP(        0, n - 1,        prefix_sum, 1);}Â
// Driver codeint main(){Â Â Â Â int n = 6;Â Â Â Â int A[n] = { 1, 2, 3, 4, 2, 6 };Â
    cout << findMaxScore(A, n);    return 0;} |
Java
// Java program to find the maximum// Score after given operationsÂ
Â
class GFG{  // Memoizing by the use of a tablestatic int [][][]dp = new int[100][100][100];  // Function to calculate maximum scorestatic int MaximumScoreDP(int l, int r,                   int prefix_sum[],                   int num){    // Bse case    if (l > r)        return 0;      // If the same state has    // already been computed    if (dp[l][r][num] != -1)        return dp[l][r][num];      // Sum of array in range (l, r)    int current_sum        = prefix_sum[r]          - (l - 1 >= 0                 ? prefix_sum[l - 1]                 : 0);      // If the operation is even-numbered    // the score is decremented    if (num % 2 == 0)        current_sum *= -1;      // Exploring all paths, and storing    // maximum value in DP table to avoid    // further repetitive recursive calls    dp[l][r][num] = current_sum                    + Math.max(                          MaximumScoreDP(                              l + 1, r,                              prefix_sum,                              num + 1),                          MaximumScoreDP(                              l, r - 1,                              prefix_sum,                              num + 1));      return dp[l][r][num];}  // Function to find the max scorestatic int findMaxScore(int a[], int n){    // Prefix sum array    int []prefix_sum = new int[n];      prefix_sum[0] = a[0];      // Calculating prefix_sum    for (int i = 1; i < n; i++) {        prefix_sum[i]            = prefix_sum[i - 1] + a[i];    }      // Initialising the DP table,    // -1 represents the subproblem    // hasn't been solved yet    for(int i = 0;i<100;i++){       for(int j = 0;j<100;j++){           for(int l=0;l<100;l++)           dp[i][j][l]=-1;       }   }      return MaximumScoreDP(        0, n - 1,        prefix_sum, 1);}  // Driver codepublic static void main(String[] args){    int n = 6;    int A[] = { 1, 2, 3, 4, 2, 6 };      System.out.print(findMaxScore(A, n));}}Â
// This code contributed by sapnasingh4991 |
Python3
# python3 program to find the maximum# Score after given operationsÂ
# Memoizing by the use of a tabledp = [[[-1 for x in range(100)]for y in range(100)]for z in range(100)]Â
# Function to calculate maximum scoreÂ
Â
def MaximumScoreDP(l, r, prefix_sum,                   num):Â
    # Bse case    if (l > r):        return 0Â
    # If the same state has    # already been computed    if (dp[l][r][num] != -1):        return dp[l][r][num]Â
    # Sum of array in range (l, r)    current_sum = prefix_sum[r]    if (l - 1 >= 0):        current_sum -= prefix_sum[l - 1]Â
    # If the operation is even-numbered    # the score is decremented    if (num % 2 == 0):        current_sum *= -1Â
    # Exploring all paths, and storing    # maximum value in DP table to avoid    # further repetitive recursive calls    dp[l][r][num] = (current_sum                     + max(                         MaximumScoreDP(                             l + 1, r,                             prefix_sum,                             num + 1),                         MaximumScoreDP(                             l, r - 1,                             prefix_sum,                             num + 1)))Â
    return dp[l][r][num]Â
Â
# Function to find the max scoredef findMaxScore(a, n):Â
    # Prefix sum array    prefix_sum = [0]*nÂ
    prefix_sum[0] = a[0]Â
    # Calculating prefix_sum    for i in range(1, n):        prefix_sum[i] = prefix_sum[i - 1] + a[i]Â
    # Initialising the DP table,    # -1 represents the subproblem    # hasn't been solved yet    global dpÂ
    return MaximumScoreDP(        0, n - 1,        prefix_sum, 1)Â
Â
# Driver codeif __name__ == "__main__":Â
    n = 6    A = [1, 2, 3, 4, 2, 6]Â
    print(findMaxScore(A, n)) |
C#
// C# program to find the maximum// Score after given operations    using System;Â
public class GFG{   // Memoizing by the use of a tablestatic int [,,]dp = new int[100,100,100];   // Function to calculate maximum scorestatic int MaximumScoreDP(int l, int r,                   int []prefix_sum,                   int num){    // Bse case    if (l > r)        return 0;       // If the same state has    // already been computed    if (dp[l,r,num] != -1)        return dp[l,r,num];       // Sum of array in range (l, r)    int current_sum        = prefix_sum[r]          - (l - 1 >= 0                 ? prefix_sum[l - 1]                 : 0);       // If the operation is even-numbered    // the score is decremented    if (num % 2 == 0)        current_sum *= -1;       // Exploring all paths, and storing    // maximum value in DP table to avoid    // further repetitive recursive calls    dp[l,r,num] = current_sum                    + Math.Max(                          MaximumScoreDP(                              l + 1, r,                              prefix_sum,                              num + 1),                          MaximumScoreDP(                              l, r - 1,                              prefix_sum,                              num + 1));       return dp[l,r,num];}   // Function to find the max scorestatic int findMaxScore(int []a, int n){    // Prefix sum array    int []prefix_sum = new int[n];       prefix_sum[0] = a[0];       // Calculating prefix_sum    for (int i = 1; i < n; i++) {        prefix_sum[i]            = prefix_sum[i - 1] + a[i];    }       // Initialising the DP table,    // -1 represents the subproblem    // hasn't been solved yet    for(int i = 0;i<100;i++){       for(int j = 0;j<100;j++){           for(int l=0;l<100;l++)           dp[i,j,l]=-1;       }   }       return MaximumScoreDP(        0, n - 1,        prefix_sum, 1);}   // Driver codepublic static void Main(String[] args){    int n = 6;    int []A = { 1, 2, 3, 4, 2, 6 };       Console.Write(findMaxScore(A, n));}}Â
// This code contributed by PrinciRaj1992 |
Javascript
<script>Â
// JavaScript program to find the maximum// Score after given operationsÂ
// Memoizing by the use of a tablelet dp = new Array(100);// Initialising the DP table,    // -1 represents the subproblem    // hasn't been solved yetfor(let i=0;i<100;i++){    dp[i]=new Array(100);    for(let j=0;j<100;j++)    {        dp[i][j]=new Array(100);        for(let k=0;k<100;k++)        {            dp[i][j][k]=-1;        }    }}Â
// Function to calculate maximum scorefunction MaximumScoreDP(l,r,prefix_sum,num){    // Bse case    if (l > r)        return 0;       // If the same state has    // already been computed    if (dp[l][r][num] != -1)        return dp[l][r][num];       // Sum of array in range (l, r)    let current_sum        = prefix_sum[r]          - (l - 1 >= 0                 ? prefix_sum[l - 1]                 : 0);       // If the operation is even-numbered    // the score is decremented    if (num % 2 == 0)        current_sum *= -1;       // Exploring all paths, and storing    // maximum value in DP table to avoid    // further repetitive recursive calls    dp[l][r][num] = current_sum                    + Math.max(                          MaximumScoreDP(                              l + 1, r,                              prefix_sum,                              num + 1),                          MaximumScoreDP(                              l, r - 1,                              prefix_sum,                              num + 1));       return dp[l][r][num];}Â
// Function to find the max scorefunction findMaxScore(a,n){    // Prefix sum array    let prefix_sum = new Array(n);       prefix_sum[0] = a[0];       // Calculating prefix_sum    for (let i = 1; i < n; i++) {        prefix_sum[i]            = prefix_sum[i - 1] + a[i];    }       // Initialising the DP table,    // -1 represents the subproblem    // hasn't been solved yet            return MaximumScoreDP(        0, n - 1,        prefix_sum, 1);}Â
// Driver codelet n = 6;let A=[1, 2, 3, 4, 2, 6 ];document.write(findMaxScore(A, n));Â
Â
// This code is contributed by rag2127Â
</script> |
13
Time complexity: O(N^3)
Auxiliary space: O(N^3)
Efficient approach : DP tabulation (iterative)
The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memorization(top-down) because memorization method needs extra stack space of recursion calls. In this approach we use 3D DP store computation of subproblems and find the final result using iteration and not with the help of recursion.
Steps that were to follow the above approach:
- Initialize a 3D DP array dp of size n x n x n.
- Calculate the prefix sum of the input array a in an array prefix_sum.
- Fill the dp table diagonally, considering all possible lengths of subarrays.
- For each subarray of length len, consider all possible starting indices i, ending indices j, and even-numbered operations num.
- Calculate the current sum of the subarray based on prefix_sum and the even/odd nature of the operation.
- If the subarray has only one element (i.e., i == j), store the current sum in dp[i][j][num].
- Otherwise, calculate the maximum score by exploring all possible paths, and store the maximum value in dp[i][j][num] to avoid further repetitive recursive calls.
- Return dp[0][n – 1][1] as the maximum score.
Below is the implementation of the above approach:
C++
// C++ program to find the maximum// Score after given operations#include <bits/stdc++.h>using namespace std;Â
// Function to find the max scoreint findMaxScore(int a[], int n){Â
    // initialize Dp to store computation of subproblems    int dp[n][n][n] = { 0 };Â
    // Prefix sum array    int prefix_sum[n] = { 0 };    prefix_sum[0] = a[0];Â
    // Calculating prefix_sum    for (int i = 1; i < n; i++) {        prefix_sum[i] = prefix_sum[i - 1] + a[i];    }Â
    // Filling the table diagonally    for (int len = 1; len <= n; len++) {        for (int i = 0; i + len - 1 < n; i++) {            int j = i + len - 1;            for (int num = 1; num <= n; num++) {                // Sum of array in range (l, r)                int current_sum                    = prefix_sum[j]                      - (i - 1 >= 0 ? prefix_sum[i - 1]                                    : 0);                if (num % 2 == 0) {                    // If the operation is even-numbered                    // the score is decremented                    current_sum *= -1;                }                if (i == j) {                    dp[i][j][num] = current_sum;                }                else {                    // Exploring all paths, and storing                    // maximum value in DP table to avoid                    // further repetitive recursive calls                    dp[i][j][num] = max(                        current_sum + dp[i + 1][j][num + 1],                        current_sum                            + dp[i][j - 1][num + 1]);                }            }        }    }Â
    return dp[0][n - 1][1];}Â
// Driver codeint main(){Â Â Â Â int n = 6;Â Â Â Â int A[n] = { 1, 2, 3, 4, 2, 6 };Â Â Â Â cout << findMaxScore(A, n);Â Â Â Â return 0;} |
Java
import java.util.*;Â
class GFG {    // Function to find the max score    static int findMaxScore(int[] a, int n)    {        // Initialize DP to store computation of subproblems        int[][][] dp = new int[n + 3][n + 3][n + 3];Â
        // Prefix sum array        int[] prefixSum = new int[n];        prefixSum[0] = a[0];Â
        // Calculating prefix_sum        for (int i = 1; i < n; i++) {            prefixSum[i] = prefixSum[i - 1] + a[i];        }Â
        // Filling the table diagonally        for (int length = 1; length <= n; length++) {            for (int i = 0; i + length - 1 < n; i++) {                int j = i + length - 1;                for (int num = 1; num <= n; num++) {                    // Sum of array in range (l, r)                    int currentSum                        = prefixSum[j]                          - (i - 1 >= 0 ? prefixSum[i - 1]                                        : 0);Â
                    // If the operation is even-numbered,                    // the score is decremented                    if (num % 2 == 0) {                        currentSum *= -1;                    }Â
                    if (i == j) {                        dp[i][j][num] = currentSum;                    }                    else {                        // Exploring all paths, and storing                        // maximum value in DP table                        dp[i][j][num] = Math.max(                            currentSum                                + dp[i + 1][j][num + 1],                            currentSum                                + dp[i][j - 1][num + 1]);                    }                }            }        }Â
        return dp[0][n - 1][1];    }Â
    // Driver code    public static void main(String[] args)    {        int n = 6;        int[] A = { 1, 2, 3, 4, 2, 6 };        System.out.println(findMaxScore(A, n));    }} |
Python3
# Python3 program to find the maximum# Score after given operationsdef findMaxScore(a, n):    # Initialize DP to store computation of subproblems    dp = [[[0] * (n + 3) for _ in range(n+3)] for _ in range(n+3)]Â
    # Prefix sum array    prefix_sum = [0] * n    prefix_sum[0] = a[0]Â
    # Calculating prefix_sum    for i in range(1, n):        prefix_sum[i] = prefix_sum[i - 1] + a[i]Â
    # Filling the table diagonally    for length in range(1, n + 1):        for i in range(n - length + 1):            j = i + length - 1            for num in range(1, n + 1):                # Sum of array in range (l, r)                current_sum = prefix_sum[j] - (prefix_sum[i - 1] if i - 1 >= 0 else 0)                if num % 2 == 0:                    # If the operation is even-numbered, the score                     # is decremented                    current_sum *= -1                if i == j:                    dp[i][j][num] = current_sum                else:                    # Exploring all paths and storing maximum value in                     # DP table                    dp[i][j][num] = max(current_sum + dp[i + 1][j][num + 1],                                         current_sum + dp[i][j - 1][num + 1])                     Â
    return dp[0][n - 1][1]Â
# Driver coden = 6A = [1, 2, 3, 4, 2, 6]print(findMaxScore(A, n)) |
C#
using System;Â
class GFG {    // Function to find the max score    static int FindMaxScore(int[] a, int n)    {        // Initialize DP to store computation of subproblems        int[, , ] dp = new int[n + 3, n + 3, n + 3];Â
        // Prefix sum array        int[] prefixSum = new int[n];        prefixSum[0] = a[0];Â
        // Calculating prefix_sum        for (int i = 1; i < n; i++) {            prefixSum[i] = prefixSum[i - 1] + a[i];        }Â
        // Filling the table diagonally        for (int length = 1; length <= n; length++) {            for (int i = 0; i + length - 1 < n; i++) {                int j = i + length - 1;                for (int num = 1; num <= n; num++) {                    // Sum of array in range (l, r)                    int currentSum                        = prefixSum[j]                          - (i - 1 >= 0 ? prefixSum[i - 1]                                        : 0);Â
                    // If the operation is even-numbered,                    // the score is decremented                    if (num % 2 == 0) {                        currentSum *= -1;                    }Â
                    if (i == j) {                        dp[i, j, num] = currentSum;                    }                    else {                        // Exploring all paths, and storing                        // maximum value in DP table                        dp[i, j, num] = Math.Max(                            currentSum                                + dp[i + 1, j, num + 1],                            currentSum                                + dp[i, j - 1, num + 1]);                    }                }            }        }Â
        return dp[0, n - 1, 1];    }Â
    // Driver code    static void Main()    {        int n = 6;        int[] A = { 1, 2, 3, 4, 2, 6 };        Console.WriteLine(FindMaxScore(A, n));    }} |
Javascript
// Javascript program to find the maximum// Score after given operationsÂ
// Function to find the max scorefunction findMaxScore(a, n) {    // initialize Dp to store computation of subproblems    let dp = new Array(n).fill(0).map(() => new Array(n).fill(0).map(() => new Array(n).fill(0)));       // Prefix sum array      let prefix_sum = new Array(n).fill(0);      prefix_sum[0] = a[0];       // Calculating prefix_sum      for (let i = 1; i < n; i++) {        prefix_sum[i] = prefix_sum[i - 1] + a[i];      }        // Filling the table diagonally      for (let len = 1; len <= n; len++) {        for (let i = 0; i + len - 1 < n; i++) {            let j = i + len - 1;            for (let num = 1; num <= n; num++) {             // Sum of array in range (l, r)            let current_sum = prefix_sum[j] - (i - 1 >= 0 ? prefix_sum[i - 1] : 0);            if (num % 2 === 0) {                // If the operation is even-numbered                // the score is decremented              current_sum *= -1;            }            if (i === j) {              dp[i][j][num] = current_sum;            }            else {                              // Exploring all paths, and storing            // maximum value in DP table to avoid            // further repetitive recursive calls              dp[i][j][num] = Math.max(                current_sum + dp[i + 1][j][num + 1],                current_sum + dp[i][j - 1][num + 1]              );            }          }        }      }      return dp[0][n - 1][1];}Â
// Driver codelet n = 6;let A = [1, 2, 3, 4, 2, 6];console.log(findMaxScore(A, n)); |
Output:
13
Time complexity: O(N^3)
Auxiliary space: O(N^3)
Efficient Approach: Space Optimization
In previous approach the current value dp[i][j][num] is only depend upon the current and previous row values of DP. So to optimize the space complexity we use a single 2D matrix instead of 3d array to store the computations.
Follow the step below to implement the above idea:
- Initialize a 2D array dp of size n x n to store maximum scores.
- Calculate the prefix sum array prefix_sum by iterating through the input array a[] and adding the previous prefix sum.
- Iterate over different lengths of subarrays (len) and starting indices of subarrays (i).
- Iterate over the number of elements to consider in the subarray (num).
- Calculate the current sum of the subarray and handle even/odd number conditions.
- Determine the maximum score by choosing between including or excluding the current element.
- Return the maximum score for the entire array considering 1 element (dp[0][1]).
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>using namespace std;Â
int findMaxScore(int a[], int n){  // DP array to store maximum scores    int dp[n][n] = {0};              // Prefix sum array to calculate subarray sums    int prefix_sum[n] = {0};      Â
  // Initialize the prefix sum with the first element    prefix_sum[0] = a[0];              for (int i = 1; i < n; i++) {      // Calculate prefix sum        prefix_sum[i] = prefix_sum[i - 1] + a[i];       }Â
    for (int len = 1; len <= n; len++) {        for (int i = 0; i + len - 1 < n; i++) {            int j = i + len - 1;        Â
            for (int num = 1; num <= n; num++) {                int current_sum = prefix_sum[j] - (i - 1 >= 0 ? prefix_sum[i - 1] : 0);                // Calculate the sum of the current subarrayÂ
                if (num % 2 == 0) {                  // Multiply sum by -1 if num is even                    current_sum *= -1;                   }Â
                if (i == j) {                   // Base case: subarray has only one element                    dp[i][num] = current_sum;                 } else {                    // Choose the maximum score among two options:                    // 1. Include the current element and move to the next element                    // 2. Exclude the current element and move to the next element                    dp[i][num] = max(current_sum + dp[i + 1][num + 1], current_sum + dp[i][num + 1]);                }            }        }    }Â
    return dp[0][1]; }Â
int main(){Â Â Â Â int n = 6;Â Â Â Â int A[] = {1, 2, 3, 4, 2, 6};Â Â Â Â cout << findMaxScore(A, n) << endl;Â Â Â Â return 0;}Â
// --by bhardwajji |
Javascript
function GFG(a, n) {  // Initialize an array to store maximum scores  const dp = new Array(n).fill(0).map(() => new Array(n).fill(0));  // Initialize an array for prefix sums to   // calculate subarray sums  const prefixSum = new Array(n).fill(0);  // Initialize the prefix sum with   // the first element  prefixSum[0] = a[0];  for (let i = 1; i < n; i++) {    // Calculate prefix sum    prefixSum[i] = prefixSum[i - 1] + a[i];  }  for (let len = 1; len <= n; len++) {    for (let i = 0; i + len - 1 < n; i++) {      const j = i + len - 1;      for (let num = 1; num <= n; num++) {        let currentSum = prefixSum[j] - (i - 1 >= 0 ? prefixSum[i - 1] : 0);        // Calculate the sum of the current subarray        if (num % 2 === 0) {          // Multiply sum by -1 if num is even          currentSum *= -1;        }        if (i === j) {          // Base case: subarray has only one element          dp[i][num] = currentSum;        } else {          dp[i][num] = Math.max(currentSum + dp[i + 1][num + 1], currentSum + dp[i][num + 1]);        }      }    }  }  return dp[0][1];}function main() {  const n = 6;  const A = [1, 2, 3, 4, 2, 6];  console.log(GFG(A, n));}main(); |
13
Time complexity: O(N^3)
Auxiliary space: O(N^2)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



