给定一个由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个元素而生成的总和,即:
maximumSum(j, i + 1)
因此,递归关系为:
dp[i][j] = max(a[i] * j + maximumSum(j + 1, i + 1), maximumSum(j, i + 1))
- 通过考虑每个数组元素的上述条件,继续更新dp [] []表,并打印整个数组中可能的最大和。
- 通过选择a [i]作为子序列的第j个元素生成的总和,即:
下面是上述方法的实现:
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
输出:
14
时间复杂度: O(N 2 )
辅助空间: O(N 2 )