Maximize the subarray sum after multiplying all elements of any subarray with X

Given an array arr[] of N integers and an integer X. We can choose any sub-array and multiply all its element by X. After multiplication, find the sub-array with the maximum sum. The task is to multiply the sub-array in such a way that the final sub-array sum is maximized.

Examples:

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

Approach: The problem cannot be solved using a greedy approach. Greedy approach fails in many cases one of them being a[] = { -3, 8, -2, 1, 6 } and x = -1. We will use Dynamic Programming to solve the above problem. Let dp[ind][state], where ind is the current index in the array and there are 3 states.

Kadane’s algorithm has been used along with DP to get the maximum subarray sum simultaneously.

Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
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;
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 */
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// PHP implementation of the approach 
  
$N = 5; 
  
// Function to return the maximum sum 
function 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)); 
    
    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 
function getMaximumSum($a, $n, $x
  
    // Initialize dp with -1 
    $dp = array(array()) ;
      
    for($i = 0; $i < $n; $i++)
    {
        for($j = 0; $j < 3; $j++)
        {
            $dp[$i][$j] = -1;
        }
    }
  
    // Iterate from every position and find the 
    // maximum sum which is possible 
    $maxi = 0; 
    for ($i = 0; $i < $n; $i++) 
        $maxi = max($maxi, func($i, 0, $a, $dp, $n, $x)); 
  
    return $maxi
  
    // Driver code 
    $a = array( -3, 8, -2, 1, -6 ); 
    $n = count($a) ;
    $x = -1; 
  
    echo getMaximumSum($a, $n, $x); 
      
    // This code is contributed by Ryuga
?>
chevron_right

Output:
15

Time Complexity: O(N * 3)
Auxiliary Space: O(N * 3)




Striver(underscore)79 at Codechef and codeforces D

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.





Article Tags :