📌  相关文章
📜  查找长度小于或等于m的最大和数组

📅  最后修改于: 2021-05-04 17:24:41             🧑  作者: Mango

给定n个由整数组成的不同长度的数组,目标是从一个数组中选取最多一个子数组,以使所有选取的子数组的组合长度不大于m,并且它们的元素之和最大(也给定该值的n不能超过100)

先决条件:背包问题

例子 :

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

此问题类似于背包问题。在该问题中,您必须选择一个元素或将其保留。我们将在此处采用相同的策略。
假设这n个数组中的元素总数不超过10 ^ 5。还已知m最多为10 ^ 3,并且输入数组可以包含负数。首先,制作大小为n * m的DP表(二维数组),然后预先计算数组的累加和,以便可以轻松计算该数组从1到n的每个长度的最大和。给定的数组,长度k可以有一个最大的连续和,其中k是从1到数组的长度。
详细地,一一处理输入数组。首先,计算从1到长度的所有大小的已处理数组的最大和子数组。然后,使用这些值更新动态编程表,然后开始处理下一个数组。

算法 :

  1. 从n个数组中选择一个数组并开始处理它。
  2. 计算长度k的最大连续和,k从1到数组的长度,并将其保存在数组maxSum中。
  3. 现在,通过存储每个长度从0到m的最大和来填充DP表。
  4. 在最后一步中,我们遍历DP表的最后一行(第n行),并选择可能的最大和并将其返回。

    下面是上述方法的实现:

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


    输出 :
    Maximum sum can be obtained is : 39
    

    时间复杂度: O( m^2 n)