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.Â
Â
- The first state defines that no sub-array has been chosen till index ind to be multiplied with X.
- The second state defines that the current element at index ind is in the sub-array which is multiplied with X.
- The third state defines that the sub-array has already been chosen.
Kadane’s algorithm has been used along with DP to get the maximum subarray sum simultaneously.Â
Below is the implementation of the above approach:Â
Â
C++
// C++ implementation of the approach#include <bits/stdc++.h>using namespace std;#define N 5Â
// Function to return the maximum sumint 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 sumint 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 codeint 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 approachclass GFG{Â
    static int N = 5;Â
// Function to return the maximum sumstatic 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 sumstatic 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 codepublic 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 sumdef 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 sumdef 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 approachusing System;Â
class GFG{Â
    static int N = 5;Â
// Function to return the maximum sumstatic 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 sumstatic 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 codepublic 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 */ |
Javascript
<script>Â
// JavaScript implementation of the approach   var 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];        }Â
        var 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    function getMaximumSum(a , n , x) {Â
        // Initialize dp with -1        var dp = Array(n).fill().map(()=>Array(3).fill(0));        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        var maxi = 0;        for (i = 0; i < n; i++) {            maxi = Math.max(maxi, func(i, 0, a, dp, n, x));        }Â
        return maxi;    }Â
    // Driver code             var a = [ -3, 8, -2, 1, -6 ];        var n = a.length;        var x = -1;        document.write(getMaximumSum(a, n, x));Â
// This code contributed by Rajput-JiÂ
</script> |
PHP
<?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?> |
15
Time Complexity: O(N * 3)Â
Auxiliary Space: O(N * 3)
Â
Efficient approach : Using DP Tabulation method ( Iterative approach )
The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memoization(top-down) because memoization method needs extra stack space of recursion calls.
Steps to solve this problem :
- Create a DP to store the solution of the subproblems.
- Initialize the DP with base cases
- Now Iterate over subproblems to get the value of current problem form previous computation of subproblems stored in DP.
- Create a variable ans to keep track of values of DP in each condition.
- After iteration from loop create a variable maxi to store the maximum sum and update it by iterate over Dp.
- Return the final solution stored in maxi.
Implementation :
Â
C++
#include <bits/stdc++.h>using namespace std;#define N 5Â
// Function to return the maximum sumint getMaximumSum(int a[], int n, int x){Â Â Â Â int dp[n][3];Â
    // Initializing the dp array    for(int i=0; i<n; i++){        dp[i][0] = a[i];        dp[i][1] = a[i]*x;        dp[i][2] = a[i];    }Â
    // Applying the recurrence relation    for(int i=n-2; i>=0; i--){        for(int j=0; j<3; j++){                         // to track the answer in each condition            int ans = 0;            if(j==0){                ans = max(dp[i][j], dp[i+1][j]+a[i]);                ans = max(ans, dp[i+1][j+1]+x*a[i]);            }            else if(j==1){                ans = max(dp[i][j], dp[i+1][j]+x*a[i]);                ans = max(ans, dp[i+1][j+1]+a[i]);            }            else{                ans = max(dp[i][j], dp[i+1][j]+a[i]);            }                         // update DP             dp[i][j] = ans;        }    }Â
    // Finding the maximum sum from dp array    int maxi = 0;    for (int i = 0; i < n; i++)        maxi = max(maxi, dp[i][0]);           // return final answer    return maxi;}Â
// Driver codeint main(){    int a[] = { -3, 8, -2, 1, -6 };    int n = sizeof(a) / sizeof(a[0]);    int x = -1;    // function call    cout << getMaximumSum(a, n, x);Â
    return 0;} |
Java
import java.util.*;Â
public class Main {Â
  public static int getMaximumSum(int[] a, int n, int x)  {Â
    // Initializing the dp array    int[][] dp = new int[n][3];    for (int i = 0; i < n; i++) {      dp[i][0] = a[i];      dp[i][1] = a[i] * x;      dp[i][2] = a[i];    }Â
    // Applying the recurrence relation    for (int i = n - 2; i >= 0; i--) {      for (int j = 0; j < 3; j++) {Â
        // to track the answer in each condition        int ans = 0;        if (j == 0) {          ans = Math.max(dp[i][j],                         dp[i + 1][j] + a[i]);          ans = Math.max(ans, dp[i + 1][j + 1]                         + x * a[i]);        }        else if (j == 1) {          ans = Math.max(dp[i][j],                         dp[i + 1][j] + x * a[i]);          ans = Math.max(ans,                         dp[i + 1][j + 1] + a[i]);        }        else {          ans = Math.max(dp[i][j],                         dp[i + 1][j] + a[i]);        }Â
        // update DP        dp[i][j] = ans;      }    }Â
    // Finding the maximum sum from dp array    int maxi = 0;    for (int i = 0; i < n; i++) {      maxi = Math.max(maxi, dp[i][0]);    }Â
    // return final answer    return maxi;  }Â
  public static void main(String[] args)  {    int[] a = { -3, 8, -2, 1, -6 };    int n = a.length;    int x = -1;Â
    // function call    System.out.println(getMaximumSum(a, n, x));  }}Â
// This code is contributed by user_dtewbxkn77n |
Python3
# Function to return the maximum sumdef getMaximumSum(a, n, x):       # Initializing the dp array    dp = [[0 for j in range(3)] for i in range(n)]    for i in range(n):        dp[i][0] = a[i]        dp[i][1] = a[i] * x        dp[i][2] = a[i]Â
    # Applying the recurrence relation    for i in range(n-2, -1, -1):        for j in range(3):                       # to track the answer in each condition            ans = 0            if j == 0:                ans = max(dp[i][j], dp[i+1][j]+a[i])                ans = max(ans, dp[i+1][j+1]+x*a[i])            elif j == 1:                ans = max(dp[i][j], dp[i+1][j]+x*a[i])                ans = max(ans, dp[i+1][j+1]+a[i])            else:                ans = max(dp[i][j], dp[i+1][j]+a[i])                         # update DP            dp[i][j] = ansÂ
    # Finding the maximum sum from dp array    maxi = 0    for i in range(n):        maxi = max(maxi, dp[i][0])Â
    # return final answer    return maxiÂ
# Driver codeif __name__ == '__main__':    a = [-3, 8, -2, 1, -6]    n = len(a)    x = -1         # function call    print(getMaximumSum(a, n, x)) |
C#
using System;Â
class Program {Â Â Â Â const int N = 5;Â
    // Function to return the maximum sum    static int GetMaximumSum(int[] a, int n, int x)    {        int[, ] dp = new int[n, 3];Â
        // Initializing the dp array        for (int i = 0; i < n; i++) {            dp[i, 0] = a[i];            dp[i, 1] = a[i] * x;            dp[i, 2] = a[i];        }Â
        // Applying the recurrence relation        for (int i = n - 2; i >= 0; i--) {            for (int j = 0; j < 3; j++) {                // to track the answer in each condition                int ans = 0;                if (j == 0) {                    ans = Math.Max(dp[i, j],                                   dp[i + 1, j] + a[i]);                    ans = Math.Max(ans, dp[i + 1, j + 1]                                            + x * a[i]);                }                else if (j == 1) {                    ans = Math.Max(dp[i, j],                                   dp[i + 1, j] + x * a[i]);                    ans = Math.Max(ans,                                   dp[i + 1, j + 1] + a[i]);                }                else {                    ans = Math.Max(dp[i, j],                                   dp[i + 1, j] + a[i]);                }Â
                // update DP                dp[i, j] = ans;            }        }Â
        // Finding the maximum sum from dp array        int maxi = 0;        for (int i = 0; i < n; i++) {            maxi = Math.Max(maxi, dp[i, 0]);        }Â
        // return final answer        return maxi;    }Â
    // Driver code    static void Main()    {        int[] a = { -3, 8, -2, 1, -6 };        int n = a.Length;        int x = -1;        // function call        Console.WriteLine(GetMaximumSum(a, n, x));    }} |
Javascript
// Function to return the maximum sumfunction getMaximumSum(a, n, x) {    // Initializing the dp array    let dp = Array.from({ length: n }, () => Array(3).fill(0));    for (let i = 0; i < n; i++) {        dp[i][0] = a[i];        dp[i][1] = a[i] * x;        dp[i][2] = a[i];    }Â
    // Applying the recurrence relation    for (let i = n - 2; i >= 0; i--) {        for (let j = 0; j < 3; j++) {            // to track the answer in each condition            let ans = 0;            if (j === 0) {                ans = Math.max(dp[i][j], dp[i + 1][j] + a[i]);                ans = Math.max(ans, dp[i + 1][j + 1] + x * a[i]);            } else if (j === 1) {                ans = Math.max(dp[i][j], dp[i + 1][j] + x * a[i]);                ans = Math.max(ans, dp[i + 1][j + 1] + a[i]);            } else {                ans = Math.max(dp[i][j], dp[i + 1][j] + a[i]);            }            // update DP            dp[i][j] = ans;        }    }Â
    // Finding the maximum sum from dp array    let maxi = 0;    for (let i = 0; i < n; i++) {        maxi = Math.max(maxi, dp[i][0]);    }Â
    // return final answer    return maxi;}Â
// Driver codelet a = [-3, 8, -2, 1, -6];let n = a.length;let x = -1;Â
// function callconsole.log(getMaximumSum(a, n, x)); |
Output:Â
15
Â
Time Complexity: O(N * 3)Â
Auxiliary Space: O(N * 3)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



