Find maximum sum array of length less than or equal to m
Given n arrays of different lengths consisting of integers, the target is to pick atmost one subarray from an array such that the combined length of all picked sub arrays does not become greater than m and also sum of their elements is maximum.(also given that value of n can not be more than 100) Prerequisite: Knapsack Problem Examples :
Input : n = 5, m = 6,
arr[][m] = {{3, 2, 3, 5},
{2, 7, -1},
{2, 8, 10},
{4, 5, 2, 6, 1}
{3, 2, 3, -2}};
Output : Maximum sum can be obtained is 39
Explanation : We are allowed to pick at most one subarray from every array.
We get total sum 39 as ((5) + (7) + (8 + 10) + (4 + 5))
Input : n = 3, m = 4
arr[][m] = {{2, 3, 2},
{3, -1, 7, 10},
{4, 8, 10, -5, 3}};
Output : Maximum sum can be obtained is 35
This problem is similar to Knapsack problem.where you have to either pick an element or leave it. We will have the same strategy here. Given that the total number of elements in these n arrays is at most 10^5. It is also known that m is at most 10^3 and the input arrays can contain negative numbers. First, make a DP table (2D array) of size n * m and then, pre-compute the cumulative sum of an array so that the maximum sum of every length from 1 to n of that array can be easily computed so that for every given array there can be a maximum continuous sum for length k, where k is from 1 to length of the array. In detail, process input arrays one by one. First, compute the maximum sum subarrays of the processed array for all sizes from 1 to length. Then, update our dynamic programming table with these values and we start processing the next array. Algorithm :
- Pick one array from n arrays and start processing it.
- Calculate the maximum contiguous sum for length k, k is from 1 to the length of the array, and save it in the array maxSum.
- Now, fill the DP table by storing the maximum sum possible for every length 0 to m.
- In the last step, we traverse the last row(nth row) of DP table and pick the maximum sum possible and return it.
Below is the implementation of the above approach :
C++
#include <bits/stdc++.h>
using namespace std;
#define N 105
#define M 1001
#define INF -1111111111
int maxSum( int arr[][N])
{
int dp[N][M];
int current_arr[M];
int maxsum[M];
memset (dp, -1, sizeof (dp[0][0]) * N * M);
current_arr[0] = 0;
dp[0][0] = 0;
for ( int i = 1; i <= 5; i++) {
int len = arr[i - 1][0];
for ( int j = 1; j <= len; j++) {
current_arr[j] = arr[i - 1][j];
current_arr[j] += current_arr[j - 1];
maxsum[j] = INF;
}
for ( int j = 1; j <= len && j <= 6; j++)
for ( int k = 1; k <= len; k++)
if (j + k - 1 <= len)
maxsum[j] = max(maxsum[j],
current_arr[j + k - 1] -
current_arr[k - 1]);
for ( int j = 0; j <= 6; j++)
dp[i][j] = dp[i - 1][j];
for ( int j = 1; j <= 6; j++)
for ( int cur = 1; cur <= j && cur <= len; cur++)
dp[i][j] = max(dp[i][j],
dp[i - 1][j - cur] +
maxsum[cur]);
}
int ans = 0;
for ( int i = 0; i <= 6; i++)
ans = max(ans, dp[5][i]);
return ans;
}
int main()
{
int arr[][N] = { { 3, 2, 3, 5 },
{ 2, 7, -1 },
{ 2, 8, 10 },
{ 4, 5, 2, 6, 1 },
{ 3, 2, 3, -2 } };
cout << "Maximum sum can be obtained "
<< "is : " << maxSum(arr) << "\n" ;
}
|
Java
import java.io.*;
public class GFG
{
static int N = 105 ;
static int M = 1001 ;
static int INF = - 1111111111 ;
static int maxSum( int [][]arr)
{
int [][]dp = new int [N][M];
int []current_arr = new int [M];
int []maxsum = new int [M];
for ( int i = 0 ; i < N; i++)
{
for ( int j = 0 ; j < M ; j++)
dp[i][j] = - 1 ;
}
current_arr[ 0 ] = 0 ;
dp[ 0 ][ 0 ] = 0 ;
for ( int i = 1 ; i <= 5 ; i++)
{
int len = arr[i - 1 ][ 0 ];
for ( int j = 1 ; j <= len; j++)
{
current_arr[j] = arr[i - 1 ][j];
current_arr[j] += current_arr[j - 1 ];
maxsum[j] = INF;
}
for ( int j = 1 ; j <= len && j <= 6 ; j++)
for ( int k = 1 ; k <= len; k++)
if (j + k - 1 <= len)
maxsum[j] = Math.max(maxsum[j],
current_arr[j + k - 1 ] -
current_arr[k - 1 ]);
for ( int j = 0 ; j <= 6 ; j++)
dp[i][j] = dp[i - 1 ][j];
for ( int j = 1 ; j <= 6 ; j++)
for ( int cur = 1 ; cur <= j &&
cur <= len; cur++)
dp[i][j] = Math.max(dp[i][j],
dp[i - 1 ][j - cur] +
maxsum[cur]);
}
int ans = 0 ;
for ( int i = 0 ; i <= 6 ; i++)
ans = Math.max(ans, dp[ 5 ][i]);
return ans;
}
public static void main(String args[])
{
int [][] arr = {
{ 3 , 2 , 3 , 5 },
{ 2 , 7 , - 1 },
{ 2 , 8 , 10 },
{ 4 , 5 , 2 , 6 , 1 },
{ 3 , 2 , 3 , - 2 }
};
System.out.println( "Maximum sum can be " +
"obtained is : " +
maxSum(arr));
}
}
|
Python3
N = 105
M = 1001
INF = - 1111111111
def maxSum(arr):
dp = [[ - 1 for x in range (M)]
for y in range (N)]
current_arr = [ 0 ] * M
maxsum = [ 0 ] * M
current_arr[ 0 ] = 0
dp[ 0 ][ 0 ] = 0
for i in range ( 1 , 6 ):
len = arr[i - 1 ][ 0 ]
for j in range ( 1 , len + 1 ):
current_arr[j] = arr[i - 1 ][j]
current_arr[j] + = current_arr[j - 1 ]
maxsum[j] = INF
j = 1
while j < = len and j < = 6 :
for k in range ( 1 , len + 1 ):
if (j + k - 1 < = len ):
maxsum[j] = max (maxsum[j],
current_arr[j + k - 1 ] -
current_arr[k - 1 ])
j + = 1
for j in range ( 7 ):
dp[i][j] = dp[i - 1 ][j]
for j in range ( 1 , 7 ):
cur = 1
while cur < = j and cur < = len :
dp[i][j] = max (dp[i][j],
dp[i - 1 ][j - cur] +
maxsum[cur])
cur + = 1
ans = 0
for i in range ( 7 ):
ans = max (ans, dp[ 5 ][i])
return ans
if __name__ = = "__main__" :
arr = [ [ 3 , 2 , 3 , 5 ],
[ 2 , 7 , - 1 ],
[ 2 , 8 , 10 ],
[ 4 , 5 , 2 , 6 , 1 ],
[ 3 , 2 , 3 , - 2 ] ]
print ( "Maximum sum can be obtained" ,
"is : " , maxSum(arr))
|
C#
using System;
class GFG
{
static int N = 105;
static int M = 1001;
static int INF = -1111111111;
static int maxSum( int [][]arr)
{
int [,]dp = new int [N, M];
int []current_arr = new int [M];
int []maxsum = new int [M];
for ( int i = 0; i < N; i++)
{
for ( int j = 0; j < M ; j++)
dp[i, j] = -1;
}
current_arr[0] = 0;
dp[0, 0] = 0;
for ( int i = 1; i <= 5; i++)
{
int len = arr[i - 1][0];
for ( int j = 1; j <= len; j++)
{
current_arr[j] = arr[i - 1][j];
current_arr[j] += current_arr[j - 1];
maxsum[j] = INF;
}
for ( int j = 1; j <= len && j <= 6; j++)
for ( int k = 1; k <= len; k++)
if (j + k - 1 <= len)
maxsum[j] = Math.Max(maxsum[j],
current_arr[j + k - 1] -
current_arr[k - 1]);
for ( int j = 0; j <= 6; j++)
dp[i, j] = dp[i - 1, j];
for ( int j = 1; j <= 6; j++)
for ( int cur = 1; cur <= j &&
cur <= len; cur++)
dp[i, j] = Math.Max(dp[i, j],
dp[i - 1, j - cur] +
maxsum[cur]);
}
int ans = 0;
for ( int i = 0; i <= 6; i++)
ans = Math.Max(ans, dp[5, i]);
return ans;
}
static void Main()
{
int [][] arr = new int [][]
{
new int []{ 3, 2, 3, 5 },
new int []{ 2, 7, -1 },
new int []{ 2, 8, 10 },
new int []{ 4, 5, 2, 6, 1 },
new int []{ 3, 2, 3, -2 }
};
Console.Write ( "Maximum sum can be " +
"obtained is : " +
maxSum(arr) + "\n" );
}
}
|
Javascript
let N = 105;
let M = 1001;
let INF = -1111111111;
function maxSum(arr)
{
let dp = new Array(N);
for (let i = 0;i<N;i++){
dp[i] = new Array(M);
}
let current_arr = new Array(M);
let maxsum = new Array(M);
for (let i = 0; i < N; i++)
{
for (let j = 0; j < M ; j++){
dp[i][j] = -1;
}
}
current_arr[0] = 0;
dp[0][0] = 0;
for (let i = 1; i <= 5; i++)
{
let len = arr[i - 1][0];
for (let j = 1; j <= len; j++)
{
current_arr[j] = arr[i - 1][j];
current_arr[j] += current_arr[j - 1];
maxsum[j] = INF;
}
for (let j = 1; j <= len && j <= 6; j++)
for (let k = 1; k <= len; k++)
if (j + k - 1 <= len)
maxsum[j] = Math.max(maxsum[j],
current_arr[j + k - 1] -
current_arr[k - 1]);
for (let j = 0; j <= 6; j++)
dp[i][j] = dp[i - 1][j];
for (let j = 1; j <= 6; j++)
for (let cur = 1; cur <= j &&
cur <= len; cur++)
dp[i][j] = Math.max(dp[i][j],
dp[i - 1][j - cur] +
maxsum[cur]);
}
let ans = 0;
for (let i = 0; i <= 6; i++)
ans = Math.max(ans, dp[5][i]);
return ans;
}
let arr = [
[ 3, 2, 3, 5 ],
[ 2, 7, -1 ],
[ 2, 8, 10 ],
[ 4, 5, 2, 6, 1 ],
[ 3, 2, 3, -2 ]
];
console.log( "Maximum sum can be " + "obtained is : " + maxSum(arr));
|
OutputMaximum sum can be obtained is : 39
Time complexity : O(n)
Auxiliary Space: O(n*m)
Last Updated :
20 Dec, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...