Get the best out of our app
GeeksforGeeks App
Open App
Browser
Continue

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 ``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

 ``

Javascript

 ``

Output:

`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 ``using` `namespace` `std;``#define N 5` `// Function to return the maximum sum``int` `getMaximumSum(``int` `a[], ``int` `n, ``int` `x)``{``    ``int` `dp[n][3];` `    ``// Initializing the dp array``    ``for``(``int` `i=0; 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 code``int` `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 sum``def` `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 code``if` `__name__ ``=``=` `'__main__'``:``    ``a ``=` `[``-``3``, ``8``, ``-``2``, ``1``, ``-``6``]``    ``n ``=` `len``(a)``    ``x ``=` `-``1``    ` `    ``# function call``    ``print``(getMaximumSum(a, n, x))`

Output:

`15`

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

My Personal Notes arrow_drop_up