给定一个由N个整数组成的数组arr []和一个整数X。我们可以选择任何子数组,并将其所有元素乘以X。乘法后,找到具有最大和的子数组。任务是使子阵列相乘,以使最终子阵列总和最大化。
例子:
Input: arr[] = { -3, 8, -2, 1, -6 }, X = -1
Output: 15
Choose the sub-array with {-2, 1, -6} and multiply X.
Now the new array is {-3, 8, 2, -1, 6} whose maximum sub-array sum is 15.
Input: arr[] = {1, 2, 4, -10}, X = 2
Output: 14
方法:无法使用贪婪方法解决问题。贪婪方法在许多情况下失败,其中一种是a [] = {-3,8,-2,1,6}和x = -1 。我们将使用动态编程来解决上述问题。令dp [ind] [state] ,其中ind是数组中的当前索引,并且有3种状态。
- 第一种状态定义直到索引ind与X相乘才选择子数组。
- 第二种状态定义索引ind处的当前元素在子数组中,该子数组乘以X。
- 第三状态定义子阵列已经被选择。
Kadane的算法已与DP一起使用,以同时获得最大子阵列和。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
#define N 5
// Function to return the maximum sum
int func(int idx, int cur, int a[], int dp[N][3], int n, int x)
{
// Base case
if (idx == n)
return 0;
// If already calculated
if (dp[idx][cur] != -1)
return dp[idx][cur];
int ans = 0;
// If no elements have been chosen
if (cur == 0) {
// Do not choose any element and use
// Kadane's algorithm by taking max
ans = max(ans, a[idx] + func(idx + 1, 0, a, dp, n, x));
// Choose the sub-array and multiply x
ans = max(ans, x * a[idx] + func(idx + 1, 1, a, dp, n, x));
}
else if (cur == 1) {
// Choose the sub-array and multiply x
ans = max(ans, x * a[idx] + func(idx + 1, 1, a, dp, n, x));
// End the sub-array multiplication
ans = max(ans, a[idx] + func(idx + 1, 2, a, dp, n, x));
}
else
// No more multiplication
ans = max(ans, a[idx] + func(idx + 1, 2, a, dp, n, x));
// Memoize and return the answer
return dp[idx][cur] = ans;
}
// Function to get the maximum sum
int getMaximumSum(int a[], int n, int x)
{
// Initialize dp with -1
int dp[n][3];
memset(dp, -1, sizeof dp);
// Iterate from every position and find the
// maximum sum which is possible
int maxi = 0;
for (int i = 0; i < n; i++)
maxi = max(maxi, func(i, 0, a, dp, n, x));
return maxi;
}
// Driver code
int main()
{
int a[] = { -3, 8, -2, 1, -6 };
int n = sizeof(a) / sizeof(a[0]);
int x = -1;
cout << getMaximumSum(a, n, x);
return 0;
}
Java
// Java implementation of the approach
class GFG
{
static int N = 5;
// Function to return the maximum sum
static int func(int idx, int cur, int a[],
int dp[][], int n, int x)
{
// Base case
if (idx == n)
{
return 0;
}
// If already calculated
if (dp[idx][cur] != -1)
{
return dp[idx][cur];
}
int ans = 0;
// If no elements have been chosen
if (cur == 0)
{
// Do not choose any element and use
// Kadane's algorithm by taking max
ans = Math.max(ans, a[idx] +
func(idx + 1, 0, a, dp, n, x));
// Choose the sub-array and multiply x
ans = Math.max(ans, x * a[idx] +
func(idx + 1, 1, a, dp, n, x));
}
else if (cur == 1)
{
// Choose the sub-array and multiply x
ans = Math.max(ans, x * a[idx] +
func(idx + 1, 1, a, dp, n, x));
// End the sub-array multiplication
ans = Math.max(ans, a[idx] +
func(idx + 1, 2, a, dp, n, x));
}
else // No more multiplication
{
ans = Math.max(ans, a[idx] +
func(idx + 1, 2, a, dp, n, x));
}
// Memoize and return the answer
return dp[idx][cur] = ans;
}
// Function to get the maximum sum
static int getMaximumSum(int a[], int n, int x)
{
// Initialize dp with -1
int dp[][] = new int[n][3];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 3; j++)
{
dp[i][j] = -1;
}
}
// Iterate from every position and find the
// maximum sum which is possible
int maxi = 0;
for (int i = 0; i < n; i++)
{
maxi = Math.max(maxi, func(i, 0, a, dp, n, x));
}
return maxi;
}
// Driver code
public static void main(String[] args)
{
int a[] = {-3, 8, -2, 1, -6};
int n = a.length;
int x = -1;
System.out.println(getMaximumSum(a, n, x));
}
}
// This code has been contributed by 29AjayKumar
Python3
# Python3 implementation of the approach
N = 5
# Function to return the maximum sum
def func(idx, cur, a, dp, n, x) :
# Base case
if (idx == n) :
return 0
# If already calculated
if (dp[idx][cur] != -1):
return dp[idx][cur]
ans = 0
# If no elements have been chosen
if (cur == 0) :
# Do not choose any element and use
# Kadane's algorithm by taking max
ans = max(ans, a[idx] + func(idx + 1, 0, a, dp, n, x))
# Choose the sub-array and multiply x
ans = max(ans, x * a[idx] + func(idx + 1, 1, a, dp, n, x))
elif (cur == 1) :
# Choose the sub-array and multiply x
ans = max(ans, x * a[idx] + func(idx + 1, 1, a, dp, n, x))
# End the sub-array multiplication
ans = max(ans, a[idx] + func(idx + 1, 2, a, dp, n, x))
else :
# No more multiplication
ans = max(ans, a[idx] + func(idx + 1, 2, a, dp, n, x))
# Memoize and return the answer
dp[idx][cur] = ans
return dp[idx][cur]
# Function to get the maximum sum
def getMaximumSum(a, n, x) :
# Initialize dp with -1
dp = [[-1 for i in range(3)] for j in range(n)]
# Iterate from every position and find the
# maximum sum which is possible
maxi = 0
for i in range (0, n) :
maxi = max(maxi, func(i, 0, a, dp, n, x))
return maxi
# Driver code
a = [ -3, 8, -2, 1, -6 ]
n = len(a)
x = -1
print(getMaximumSum(a, n, x))
# This code is contributed by ihritik
C#
// C# implementation of the approach
using System;
class GFG
{
static int N = 5;
// Function to return the maximum sum
static int func(int idx, int cur, int []a,
int [,]dp, int n, int x)
{
// Base case
if (idx == n)
{
return 0;
}
// If already calculated
if (dp[idx,cur] != -1)
{
return dp[idx,cur];
}
int ans = 0;
// If no elements have been chosen
if (cur == 0)
{
// Do not choose any element and use
// Kadane's algorithm by taking max
ans = Math.Max(ans, a[idx] +
func(idx + 1, 0, a, dp, n, x));
// Choose the sub-array and multiply x
ans = Math.Max(ans, x * a[idx] +
func(idx + 1, 1, a, dp, n, x));
}
else if (cur == 1)
{
// Choose the sub-array and multiply x
ans = Math.Max(ans, x * a[idx] +
func(idx + 1, 1, a, dp, n, x));
// End the sub-array multiplication
ans = Math.Max(ans, a[idx] +
func(idx + 1, 2, a, dp, n, x));
}
else // No more multiplication
{
ans = Math.Max(ans, a[idx] +
func(idx + 1, 2, a, dp, n, x));
}
// Memoize and return the answer
return dp[idx,cur] = ans;
}
// Function to get the maximum sum
static int getMaximumSum(int []a, int n, int x)
{
// Initialize dp with -1
int [,]dp = new int[n,3];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 3; j++)
{
dp[i,j] = -1;
}
}
// Iterate from every position and find the
// maximum sum which is possible
int maxi = 0;
for (int i = 0; i < n; i++)
{
maxi = Math.Max(maxi, func(i, 0, a, dp, n, x));
}
return maxi;
}
// Driver code
public static void Main(String[] args)
{
int []a = {-3, 8, -2, 1, -6};
int n = a.Length;
int x = -1;
Console.WriteLine(getMaximumSum(a, n, x));
}
}
/* This code contributed by PrinciRaj1992 */
PHP
输出:
15
时间复杂度: O(N * 3)
辅助空间: O(N * 3)