Find maximum sum array of length less than or equal to m

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 :

  1. Pick one array from n arrays and start processing it.
  2. Calculate maximum contiguous sum for length k, k is from 1 to length of the array and save it in the array maxSum.
  3. Now, fill the DP table by storing maximum sum possible for every length 0 to m.
  4. In the last step we traverse last row(nth row) of DP table and pick maximum sum possible and return it.
  5. Below is the implementation of above approach :

    C++

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // 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";
    }

    chevron_right

    
    

    Java

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

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

    chevron_right

    
    

    C#

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

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

    chevron_right

    
    

    Output :

    Maximum sum can be obtained is : 39
    

    Time complexity : O(m^2n)



    My Personal Notes arrow_drop_up

    Check out this Author's contributed articles.

    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.



    Improved By : manishshaw1