📌  相关文章
📜  对数组执行给定操作后可能的最高分数

📅  最后修改于: 2021-09-22 10:36:02             🧑  作者: Mango

给定一个大小为N的数组A ,任务是找到这个数组可能的最大分数。数组的分数是通过对数组执行以下操作N次来计算的:

  1. 如果操作是奇数,则分数增加当前数组所有元素的总和。
  2. 如果操作是偶数,则分数减去当前数组所有元素的总和。
  3. 每次操作后,删除剩余数组的第一个或最后一个元素。

例子:

天真的方法

  1. 在每个操作中,我们必须删除最左边或最右边的元素。一个简单的方法是考虑删除元素的所有可能方法,并为每个分支计算分数并找到所有的最大分数。这可以简单地使用递归来完成。
  2. 我们需要在每个步骤中保留的信息是
    • 剩下的数组[l, r] ,其中 l 代表最左边的索引, r 代表最右边,
    • 操作编号,以及
    • 当前分数。
  3. 为了在每个递归步骤中从 [l, r] 最佳地计算任何数组的总和,我们将保留一个前缀和数组。
    使用前缀和数组,来自 [l, r] 的新和可以在 O(1) 中计算为:

下面是上述方法的实现:

C++
// C++ program to find the maximum
// score after given operations
 
#include 
using namespace std;
 
// Function to calculate
// maximum score recursively
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
           + max(
                 maxScore(
                     l + 1, r,
                     prefix_sum,
                     num + 1),
                 maxScore(
                     l, r - 1,
                     prefix_sum,
                     num + 1));
}
 
// Function to find the max score
int 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 code
int 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
import java.util.*;
 
class GFG{
 
// Function to calculate
// maximum score recursively
static 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 score
static 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 code
public 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 recursively
def 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 score
def 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 code
n = 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 operations
using System;
 
class GFG{
  
// Function to calculate
// maximum score recursively
static 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 score
static 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 code
public 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


C++
// C++ program to find the maximum
// Score after given operations
 
#include 
using namespace std;
 
// Memoizing by the use of a table
int dp[100][100][100];
 
// Function to calculate maximum score
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
                    + 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 score
int 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 code
int 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 table
static int [][][]dp = new int[100][100][100];
  
// Function to calculate maximum score
static 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 score
static 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 code
public 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 table
dp = [[[-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 score
def 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 code
if __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 table
static int [,,]dp = new int[100,100,100];
   
// Function to calculate maximum score
static 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 score
static 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 code
public 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


输出:
13

时间复杂度: O(2 N )
有效的方法

  • 在前面的方法中可以观察到我们多次计算相同的子问题,即它遵循重叠子问题的性质。所以我们可以使用动态规划来解决这个问题
  • 在上面提到的递归解决方案中,我们只需要使用 dp 表添加记忆。这些州将是:

下面是递归代码的 Memoization 方法的实现:

C++

// C++ program to find the maximum
// Score after given operations
 
#include 
using namespace std;
 
// Memoizing by the use of a table
int dp[100][100][100];
 
// Function to calculate maximum score
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
                    + 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 score
int 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 code
int 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 table
static int [][][]dp = new int[100][100][100];
  
// Function to calculate maximum score
static 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 score
static 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 code
public 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

蟒蛇3

# python3 program to find the maximum
# Score after given operations
 
# Memoizing by the use of a table
dp = [[[-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 score
def 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 code
if __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 table
static int [,,]dp = new int[100,100,100];
   
// Function to calculate maximum score
static 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 score
static 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 code
public 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


输出:
13

时间复杂度: O(N 3 )

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程