Given n arrays of different length consisting of integers, the target is to pick atmost one subarray from an array such that the combined length of all picked subarrays 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 atmost 10^5. It is also known that m is atmost 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 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 contiguous 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 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 maximum contiguous sum for length k, k is from 1 to length of the array and save it in the array maxSum.
- Now, fill the DP table by storing maximum sum possible for every length 0 to m.
- In the last step we traverse last row(nth row) of DP table and pick maximum sum possible and return it.
Below is the implementation of above approach :
C++
// A Dynamic Programming based C++ program to find
// maximum sum of array of size less than or
// equal to m from given n arrays
#include <bits/stdc++.h>
using
namespace
std;
/* N and M to define sizes of arr,
dp, current_arr and maxSum */
#define N 105
#define M 1001
// INF to define min value
#define INF -1111111111
// Function to find maximum sum
int
maxSum(
int
arr[][N])
{
// dp array of size N x M
int
dp[N][M];
// current_arr of size M
int
current_arr[M];
// maxsum of size M
int
maxsum[M];
memset
(dp, -1,
sizeof
(dp[0][0]) * N * M);
current_arr[0] = 0;
// if we have 0 elements
// from 0th array
dp[0][0] = 0;
for
(
int
i = 1; i <= 5; i++) {
int
len = arr[i - 1][0];
// compute the cumulative sum array
for
(
int
j = 1; j <= len; j++) {
current_arr[j] = arr[i - 1][j];
current_arr[j] += current_arr[j - 1];
maxsum[j] = INF;
}
// calculating the maximum contiguous
// array for every length j, j is from
// 1 to lengtn of the array
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]);
// every state is depending on
// its previous state
for
(
int
j = 0; j <= 6; j++)
dp[i][j] = dp[i - 1][j];
// computation of dp table similar
// approach as knapsack problem
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]);
}
// now we have done processing with
// the last array lets find out
// what is the maximum sum possible
int
ans = 0;
for
(
int
i = 0; i <= 6; i++)
ans = max(ans, dp[5][i]);
return
ans;
}
// Driver program
int
main()
{
// first element of each
// row is the size of that row
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
// Java program to find maximum sum
// of array of size less than or
// equal to m from given n arrays
import
java.io.*;
public
class
GFG
{
/* N and M to define
sizes of arr,
dp, current_arr
and maxSum */
static
int
N =
105
;
static
int
M =
1001
;
// INF to define
// min value
static
int
INF = -
1111111111
;
// Function to find
// maximum sum
static
int
maxSum(
int
[][]arr)
{
// dp array of size N x M
int
[][]dp =
new
int
[N][M];
// current_arr of size M
int
[]current_arr =
new
int
[M];
// maxsum of size 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
;
// if we have 0 elements
// from 0th array
dp[
0
][
0
] =
0
;
for
(
int
i =
1
; i <=
5
; i++)
{
int
len = arr[i -
1
][
0
];
// compute the cumulative
// sum array
for
(
int
j =
1
; j <= len; j++)
{
current_arr[j] = arr[i -
1
][j];
current_arr[j] += current_arr[j -
1
];
maxsum[j] = INF;
}
// calculating the maximum
// contiguous array for every
// length j, j is from 1 to
// lengtn of the array
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
]);
// every state is depending
// on its previous state
for
(
int
j =
0
; j <=
6
; j++)
dp[i][j] = dp[i -
1
][j];
// computation of dp table
// similar approach as
// knapsack problem
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]);
}
// now we have done processing
// with the last array lets
// find out what is the maximum
// sum possible
int
ans =
0
;
for
(
int
i =
0
; i <=
6
; i++)
ans = Math.max(ans, dp[
5
][i]);
return
ans;
}
// Driver Code
public
static
void
main(String args[])
{
// first element of each
// row is the size of that row
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));
}
}
// This code is contributed by
// Manish Shaw(manishshaw1)
Python3
# A Dynamic Programming based Python3
# program to find maximum sum of array
# of size less than or equal to m from
# given n arrays
# N and M to define sizes of arr,
# dp, current_arr and maxSum
N
=
105
M
=
1001
# INF to define min value
INF
=
-
1111111111
# Function to find maximum sum
def
maxSum(arr):
# dp array of size N x M
dp
=
[[
-
1
for
x
in
range
(M)]
for
y
in
range
(N)]
# current_arr of size M
current_arr
=
[
0
]
*
M
# maxsum of size M
maxsum
=
[
0
]
*
M
current_arr[
0
]
=
0
# If we have 0 elements
# from 0th array
dp[
0
][
0
]
=
0
for
i
in
range
(
1
,
6
):
len
=
arr[i
-
1
][
0
]
# Compute the cumulative sum array
for
j
in
range
(
1
,
len
+
1
):
current_arr[j]
=
arr[i
-
1
][j]
current_arr[j]
+
=
current_arr[j
-
1
]
maxsum[j]
=
INF
# Calculating the maximum contiguous
# array for every length j, j is from
# 1 to lengtn of the array
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
# Every state is depending on
# its previous state
for
j
in
range
(
7
):
dp[i][j]
=
dp[i
-
1
][j]
# computation of dp table similar
# approach as knapsack problem
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
# Now we have done processing with
# the last array lets find out
# what is the maximum sum possible
ans
=
0
for
i
in
range
(
7
):
ans
=
max
(ans, dp[
5
][i])
return
ans
# Driver code
if
__name__
=
=
"__main__"
:
# First element of each
# row is the size of that row
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))
# This code is contributed by chitranayal
C#
// C# program to find maximum sum
// of array of size less than or
// equal to m from given n arrays
using
System;
class
GFG
{
/* N and M to define
sizes of arr,
dp, current_arr
and maxSum */
static
int
N = 105;
static
int
M = 1001;
// INF to define
// min value
static
int
INF = -1111111111;
// Function to find
// maximum sum
static
int
maxSum(
int
[][]arr)
{
// dp array of size N x M
int
[,]dp =
new
int
[N, M];
// current_arr of size M
int
[]current_arr =
new
int
[M];
// maxsum of size 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;
// if we have 0 elements
// from 0th array
dp[0, 0] = 0;
for
(
int
i = 1; i <= 5; i++)
{
int
len = arr[i - 1][0];
// compute the cumulative
// sum array
for
(
int
j = 1; j <= len; j++)
{
current_arr[j] = arr[i - 1][j];
current_arr[j] += current_arr[j - 1];
maxsum[j] = INF;
}
// calculating the maximum
// contiguous array for every
// length j, j is from 1 to
// lengtn of the array
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]);
// every state is depending
// on its previous state
for
(
int
j = 0; j <= 6; j++)
dp[i, j] = dp[i - 1, j];
// computation of dp table
// similar approach as
// knapsack problem
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]);
}
// now we have done processing
// with the last array lets
// find out what is the maximum
// sum possible
int
ans = 0;
for
(
int
i = 0; i <= 6; i++)
ans = Math.Max(ans, dp[5, i]);
return
ans;
}
// Driver Code
static
void
Main()
{
// first element of each
// row is the size of that row
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"
);
}
}
// This code is contributed by
// Manish Shaw(manishshaw1)
Output :Maximum sum can be obtained is : 39
Time complexity : O(
n)
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.