给定大小为N * M的2D数组arr [] []和整数K ,任务是选择具有最大可能和的K个元素,这样,如果选择了元素arr [i] [j] ,则所有元素从第i存在于第j列的需求之前第i行被选择。
例子:
Input: arr[][] = {{10, 10, 100, 30}, {80, 50, 10, 50}}, K = 5
Output: 250
Explanation:
Selecting first 3 elements from the first row, sum = 10 + 10 + 100 = 120
Selecting first 2 elements from the second row, sum = 80 + 50 = 130
Therefore, the maximum sum = 120 + 130 = 250.
Input: arr[][] = {{30, 10, 110, 13}, {810, 152, 12, 5}, {124, 24, 54, 124}}, K = 6
Output: 1288
Explanation:
Selecting first 2 elements from the second row, sum = 810 + 152 = 962
Selecting all 4 elements from the third row, sum = 124 + 24 + 54 + 124 = 326
Therefore, the maximum sum = 962 + 326 = 1288
天真的方法:解决问题的最简单方法是根据指定的约束从给定的矩阵生成大小为K的所有可能子集,并从这些子集计算最大和。
时间复杂度: O((N * M)!/(K!)*(N * M – K)!)
辅助空间: O(1)
高效方法:可以通过使用动态编程来优化上述方法。这个想法是找到选择i元素的最大和,直到2D数组arr [] []的第j行。辅助数组dp [i] [j + 1]存储选择i个元素的最大和,直到矩阵arr [] []的第j行为止。请按照以下步骤解决问题:
- 初始化大小为(K + 1)*(N + 1)的dp [] []表,并将dp [0] [i]初始化为0 ,因为没有元素的总和等于0 。
- 将dp [i] [0]初始化为0 ,因为没有要选择的元素。
- 使用两个嵌套循环在[0,K]范围内迭代,分别使用变量i和j在[0,N]范围内迭代:
- 初始化一个变量,例如sum为0 ,以跟踪arr [] []的第j行中元素的累积和。
- 如果不需要从arr [] []的第j行中选择任何项,则将maxSum初始化为dp [i] [j ] 。
- 以k为1进行迭代,直到k> M或k> i为止:
- 增量总和+ = buy [j] [k – 1] 。
- 将现有的maxSum和(sum + dp [i – k] [j])的最大值存储在maxSum中。
- 将dp [i] [j + 1]存储为maxSum的值。
- 打印值dp [K] [N]作为K个元素的最大和,直到矩阵arr [] []的第(N – 1)行。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to return the maximum
// of two elements
int max(int a, int b)
{
return a > b ? a : b;
}
// Function to find the maximum sum
// of selecting K elements from
// the given 2D array arr[][]
int maximumsum(int arr[][4], int K,
int N, int M)
{
int sum = 0, maxSum;
int i, j, k;
// dp table of size (K+1)*(N+1)
int dp[K + 1][N + 1];
// Initialize dp[0][i] = 0
for (i = 0; i <= N; i++)
dp[0][i] = 0;
// Initialize dp[i][0] = 0
for (i = 0; i <= K; i++)
dp[i][0] = 0;
// Selecting i elements
for (i = 1; i <= K; i++) {
// Select i elements till jth row
for (j = 0; j < N; j++) {
// dp[i][j+1] is the maximum
// of selecting i elements till
// jth row
// sum = 0, to keep track of
// cummulative elements sum
sum = 0;
maxSum = dp[i][j];
// Traverse arr[j][k] until
// number of elements until k>i
for (k = 1; k <= M && k <= i; k++) {
// Select arr[j][k - 1]th item
sum += arr[j][k - 1];
maxSum
= max(maxSum,
sum + dp[i - k][j]);
}
// Store the maxSum in dp[i][j+1]
dp[i][j + 1] = maxSum;
}
}
// Return the maximum sum
return dp[K][N];
}
// Driver Code
int main()
{
int arr[][4] = { { 10, 10, 100, 30 },
{ 80, 50, 10, 50 } };
int N = 2, M = 4;
int K = 5;
// Function Call
cout << maximumsum(arr, K, N, M);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to return the maximum
// of two elements
static int max(int a, int b)
{
return a > b ? a : b;
}
// Function to find the maximum sum
// of selecting K elements from
// the given 2D array arr[][]
static int maximumsum(int arr[][], int K,
int N, int M)
{
int sum = 0, maxSum;
int i, j, k;
// dp table of size (K+1)*(N+1)
int[][] dp = new int[K + 1][N + 1];
// Initialize dp[0][i] = 0
for(i = 0; i <= N; i++)
dp[0][i] = 0;
// Initialize dp[i][0] = 0
for(i = 0; i <= K; i++)
dp[i][0] = 0;
// Selecting i elements
for(i = 1; i <= K; i++)
{
// Select i elements till jth row
for(j = 0; j < N; j++)
{
// dp[i][j+1] is the maximum
// of selecting i elements till
// jth row
// sum = 0, to keep track of
// cummulative elements sum
sum = 0;
maxSum = dp[i][j];
// Traverse arr[j][k] until
// number of elements until k>i
for(k = 1; k <= M && k <= i; k++)
{
// Select arr[j][k - 1]th item
sum += arr[j][k - 1];
maxSum = Math.max(maxSum,
sum + dp[i - k][j]);
}
// Store the maxSum in dp[i][j+1]
dp[i][j + 1] = maxSum;
}
}
// Return the maximum sum
return dp[K][N];
}
// Driver Code
public static void main(String[] args)
{
int arr[][] = { { 10, 10, 100, 30 },
{ 80, 50, 10, 50 } };
int N = 2, M = 4;
int K = 5;
// Function Call
System.out.print(maximumsum(arr, K, N, M));
}
}
// This code is contributed by susmitakundugoaldanga
Python3
# Python program for the above approach
import math;
# Function to return the maximum
# of two elements
def max(a, b):
if(a > b):
return a;
else:
return b;
# Function to find the maximum sum
# of selecting K elements from
# the given 2D array arr
def maximumsum(arr, K, N, M):
sum = 0;
maxSum = 0;
# dp table of size (K+1)*(N+1)
dp = [[0 for i in range(N + 1)] for j in range(K + 1)]
# Initialize dp[0][i] = 0
for i in range(0, N + 1):
dp[0][i] = 0;
# Initialize dp[i][0] = 0
for i in range(0, K + 1):
dp[i][0] = 0;
# Selecting i elements
for i in range(1, K + 1):
# Select i elements till jth row
for j in range(0, N):
# dp[i][j+1] is the maximum
# of selecting i elements till
# jth row
# sum = 0, to keep track of
# cummulative elements sum
sum = 0;
maxSum = dp[i][j];
# Traverse arr[j][k] until
# number of elements until k>i
for k in range(1, i + 1):
if(k > M):
break;
# Select arr[j][k - 1]th item
sum += arr[j][k - 1];
maxSum = max(maxSum, sum + dp[i - k][j]);
# Store the maxSum in dp[i][j+1]
dp[i][j + 1] = maxSum;
# Return the maximum sum
return dp[K][N];
# Driver Code
if __name__ == '__main__':
arr = [[10, 10, 100, 30], [80, 50, 10, 50]];
N = 2;
M = 4;
K = 5;
# Function Call
print(maximumsum(arr, K, N, M));
# This code is contributed by 29AjayKumar
C#
// C# program for the above approach
using System;
class GFG{
// Function to return the maximum
// of two elements
static int max(int a, int b)
{
return a > b ? a : b;
}
// Function to find the maximum sum
// of selecting K elements from
// the given 2D array [,]arr
static int maximumsum(int [,]arr, int K,
int N, int M)
{
int sum = 0, maxSum;
int i, j, k;
// dp table of size (K+1)*(N+1)
int[,] dp = new int[K + 1, N + 1];
// Initialize dp[0,i] = 0
for(i = 0; i <= N; i++)
dp[0, i] = 0;
// Initialize dp[i,0] = 0
for(i = 0; i <= K; i++)
dp[i, 0] = 0;
// Selecting i elements
for(i = 1; i <= K; i++)
{
// Select i elements till jth row
for(j = 0; j < N; j++)
{
// dp[i,j+1] is the maximum
// of selecting i elements till
// jth row
// sum = 0, to keep track of
// cummulative elements sum
sum = 0;
maxSum = dp[i, j];
// Traverse arr[j,k] until
// number of elements until k>i
for(k = 1; k <= M && k <= i; k++)
{
// Select arr[j,k - 1]th item
sum += arr[j, k - 1];
maxSum = Math.Max(maxSum,
sum + dp[i - k, j]);
}
// Store the maxSum in dp[i,j+1]
dp[i, j + 1] = maxSum;
}
}
// Return the maximum sum
return dp[K, N];
}
// Driver Code
public static void Main(String[] args)
{
int [,]arr = { { 10, 10, 100, 30 },
{ 80, 50, 10, 50 } };
int N = 2, M = 4;
int K = 5;
// Function Call
Console.Write(maximumsum(arr, K, N, M));
}
}
// This code is contributed by Amit Katiyar
Javascript
250
时间复杂度: O(K * N * M)
辅助空间: O(K * N)