📌  相关文章
📜  在阵列上执行给定操作后可能获得的最高分

📅  最后修改于: 2021-05-05 02:37:46             🧑  作者: Mango

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

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

例子:

天真的方法

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

下面是上述方法的实现:

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


输出:
13

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

  • 在以前的方法中,可以观察到我们多次计算相同的子问题,即它遵循重叠子问题的属性。因此我们可以使用动态编程来解决问题
  • 在上述递归解决方案中,我们只需要使用dp表添加备注即可。这些状态将是:

下面是递归代码的“记忆”方法的实现:

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
输出:
13

时间复杂度: O(N 3 )