给定一个由N 个整数组成的数组a[] ,任务是执行以下操作:
- 选择一个子序列,并为该子序列的每个第 p个元素计算乘积p * a[i] 。
- 计算p * a[i]的计算值的总和。
- 应该选择子序列,使其最大化所需的总和。
例子:
Input: N = 3, a[] = {-1, 3, 4}
Output: 17
Explanation:
The subsequence {-1, 3, 4} maximizes the sum = 1(-1) + 2(3) + 3(4) = 17
Input: N = 5, a[] = {-1, -9, 0, 5, -7}
Output: 14
Explanation:
The subsequence {-1, 0, 5} maximizes the sum = 1(-1) + 2(0) + 3(5) = 14
朴素方法:解决问题的最简单方法是从数组中生成所有可能的子序列并计算每个子序列的总和。最后,求最大和。
时间复杂度: O(N 3 )
辅助空间: O(N)
高效方法:上述方法可以通过使用动态规划进行优化。请按照以下步骤解决问题:
- 对于每个元素,存在两种可能性,即该元素要么是子序列的一部分,要么不是。
- 初始化一个dp[][]矩阵,其中dp[i][j]存储最大值:
- 选择a[i]作为子序列的第j个元素生成的总和,即:
a[i] * j + maximumSum(j + 1, i + 1)
- 选择a[i]作为子序列的第j个元素生成的总和,即:
- 不选择a[i]作为子序列的第j个元素生成的总和,即:
maximumSum(j, i + 1)
因此,递推关系为:
dp[i][j] = max(a[i] * j + maximumSum(j + 1, i + 1), maximumSum(j, i + 1))
- 通过考虑每个数组元素的上述条件,不断更新 dp[][] 表,并打印整个数组可能的最大和。
下面是上述方法的实现:
C++
// C++ program to implement
// the above approach
#include
using namespace std;
const int N = 6;
// Function to select the array elements to
// maximize the sum of the selected elements
int maximumSum(int a[], int count,
int index, int n,
int dp[N][N])
{
// If the entire array
// is solved
if (index == n)
return 0;
// Memoized subproblem
if (dp[index][count] != -1)
return dp[index][count];
// Calculate sum considering the
// current element in the subsequence
int take_element = a[index] * count +
maximumSum(a, count + 1,
index + 1, n, dp);
// Calculate sum without considering the
// current element in the subsequence
int dont_take = maximumSum(a, count,
index + 1, n, dp);
// Update the maximum of the above sums
// in the dp[][] table
return dp[index][count] = max(take_element,
dont_take);
}
// Driver Code
int main()
{
int n = 5;
int a[] = { -1, -9, 0, 5, -7 };
// Initialize the dp array
int dp[N][N];
memset(dp, -1, sizeof(dp));
cout << (maximumSum(a, 1, 0, n, dp));
}
// This code is contributed by Rajput-Ji
Java
// Java program to implement
// the above approach
import java.util.*;
public class GFG {
// Function to select the array elements to
// maximize the sum of the selected elements
public static int maximumSum(int[] a, int count,
int index, int n,
int[][] dp)
{
// If the entire array
// is solved
if (index == n)
return 0;
// Memoized subproblem
if (dp[index][count] != -1)
return dp[index][count];
// Calculate sum considering the
// current element in the subsequence
int take_element
= a[index] * count
+ maximumSum(a, count + 1,
index + 1, n, dp);
// Calculate sum without considering the
// current element in the subsequence
int dont_take
= maximumSum(a, count, index + 1, n, dp);
// Update the maximum of the above sums
// in the dp[][] table
return dp[index][count]
= Math.max(take_element, dont_take);
}
// Driver Code
public static void main(String args[])
{
int n = 5;
int a[] = { -1, -9, 0, 5, -7 };
// Initialize the dp array
int dp[][] = new int[n + 1][n + 1];
for (int i[] : dp)
Arrays.fill(i, -1);
System.out.println(maximumSum(a, 1, 0, n, dp));
}
}
Python3
# Python3 program to implement
# the above approach
# Function to select the array elements to
# maximize the sum of the selected elements
def maximumSum(a, count, index, n, dp):
# If the entire array
# is solved
if(index == n):
return 0
# Memoized subproblem
if(dp[index][count] != -1):
return dp[index][count]
# Calculate sum considering the
# current element in the subsequence
take_element = (a[index] * count +
maximumSum(a, count + 1,
index + 1,
n, dp))
# Calculate sum without considering the
# current element in the subsequence
dont_take = maximumSum(a, count,
index + 1, n, dp)
# Update the maximum of the above sums
# in the dp[][] table
dp[index][count] = max(take_element,
dont_take)
return dp[index][count]
# Driver Code
n = 5
a = [ -1, -9, 0, 5, -7 ]
# Initialize the dp array
dp = [[-1 for x in range(n + 1)]
for y in range(n + 1)]
# Function call
print(maximumSum(a, 1, 0, n, dp))
# This code is contributed by Shivam Singh
C#
// C# program to implement
// the above approach
using System;
class GFG{
// Function to select the array elements to
// maximize the sum of the selected elements
public static int maximumSum(int[] a, int count,
int index, int n,
int[,] dp)
{
// If the entire array
// is solved
if (index == n)
return 0;
// Memoized subproblem
if (dp[index, count] != -1)
return dp[index, count];
// Calculate sum considering the
// current element in the subsequence
int take_element = a[index] * count +
maximumSum(a, count + 1,
index + 1,
n, dp);
// Calculate sum without considering the
// current element in the subsequence
int dont_take = maximumSum(a, count,
index + 1, n, dp);
// Update the maximum of the above sums
// in the [,]dp table
return dp[index, count] = Math.Max(take_element,
dont_take);
}
// Driver Code
public static void Main(String []args)
{
int n = 5;
int []a = { -1, -9, 0, 5, -7 };
// Initialize the dp array
int [,]dp = new int[n + 1, n + 1];
for(int i = 0; i < n + 1; i++)
{
for(int j = 0; j < n + 1; j++)
{
dp[i, j] = -1;
}
}
Console.WriteLine(maximumSum(a, 1, 0, n, dp));
}
}
// This code is contributed by PrinciRaj1992
Javascript
输出:
14
时间复杂度: O(N 2 )
辅助空间: O(N 2 )
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。