给定一个大小为N的数组A ,任务是找到这个数组可能的最大分数。数组的分数是通过对数组执行以下操作N次来计算的:
- 如果操作是奇数,则分数增加当前数组所有元素的总和。
- 如果操作是偶数,则分数减去当前数组所有元素的总和。
- 每次操作后,删除剩余数组的第一个或最后一个元素。
例子:
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
天真的方法
- 在每个操作中,我们必须删除最左边或最右边的元素。一个简单的方法是考虑删除元素的所有可能方法,并为每个分支计算分数并找到所有的最大分数。这可以简单地使用递归来完成。
- 我们需要在每个步骤中保留的信息是
- 剩下的数组[l, r] ,其中 l 代表最左边的索引, r 代表最右边,
- 操作编号,以及
- 当前分数。
- 为了在每个递归步骤中从 [l, r] 最佳地计算任何数组的总和,我们将保留一个前缀和数组。
使用前缀和数组,来自 [l, r] 的新和可以在 O(1) 中计算为:
Sum(l, r) = prefix_sum[r] – prefix_sum[l-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 表添加记忆。这些州将是:
DP table states = dp[l][r][num]
where l and r represent the endpoints of the current array and num represents the operation number.
下面是递归代码的 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 现场工作专业课程和学生竞争性编程现场课程。