给定2D数组, Blocks [] []由N个可变长度的行组成。任务是从行的开头或结尾,从Blocks [] []中选择最多M个元素,且元素的总和最大。
例子:
Input: N = 3, M = 4
Blocks[][] = {{2, 3, 5}, {-1, 7}, {8, 10}}
Output: 30
Explanation:
Select {5} from 1st row.
Select {7} from 2nd row.
Select {8, 10} from 3rd row.
Input: N = 3, M = 2
Blocks[][] = {{100, 3, -1}, {-1, 7, 10}, {8, 10, 15}}
Output: 115
Explanation:
select {100} from 1st row.
Skip 2nd row.
Select {15} from 3rd row.
天真的方法:最简单的方法是遍历矩阵的所有行,并将所有元素推入向量并对其进行排序。计算最后M个元素的总和,并将其打印为所需答案。
时间复杂度: O(N * KlogK),其中K是任何块可以具有的最大大小。
辅助空间: O(N * K)
高效方法:为了优化上述方法,其思想是使用带有记忆的动态编程。请按照以下步骤操作:
- 给定N行和从各行,从第i行选择任何段,从说从左至右。
- 在i个元素的计数第i行是(R – 1 + 1),并进行到下一行。
- 要计算最大和,请使用 前缀求和技术,以便计算总和。
- 初始化2D数组dp [] [] ,其中dp [N] [M]通过从N行中选择最多M个元素来存储最大和。
- 请考虑以下两种情况:
- 要么跳过当前行。
- 从当前行中选择不超过所选元素数的任何段。
- 请考虑以下两种情况:
下面是上述方法的实现:
C++14
// C++ program for the above approach
#include
using namespace std;
// Funtion to selct m elements
// having maximum sum
long mElementsWithMaxSum(vector > matrix,
int M, int block,
vector > dp)
{
// Base case
if (block == matrix.size())
return 0;
// If precomputed subproblem occurred
if (dp[block][M] != -1)
return dp[block][M];
// Either skip the current row
long ans = mElementsWithMaxSum(matrix, M,
block + 1, dp);
// Iterate through all the possible
// segments of current row
for(int i = 0;
i < matrix[block].size(); i++)
{
for(int j = i;
j < matrix[block].size(); j++)
{
// Check if it is possible to select
// elements from i to j
if (j - i + 1 <= M)
{
// Compuete the sum of i to j as
// calculated
ans = max(ans, matrix[block][j] -
((i - 1) >= 0 ?
matrix[block][i - 1] : 0) +
mElementsWithMaxSum(matrix,
M - j +
i - 1,
block + 1, dp));
}
}
}
// Store the computed answer and return
return dp[block][M] = ans;
}
// Function to precompute the prefix sum
// for every row of the matrix
void preComputing(vector> matrix,
int N)
{
// Preprocessing to calculate sum from i to j
for(int i = 0; i < N; i++)
{
for(int j = 0; j < matrix[i].size(); j++)
{
matrix[i][j] = (j > 0 ?
matrix[i][j - 1] : 0) +
matrix[i][j];
}
}
}
// Utility function to selct m elements having
// maximum sum
void mElementsWithMaxSumUtil(vector> matrix,
int M, int N)
{
// Preprocessing step
preComputing(matrix, N);
long sum = 10;
// Initialize dp array with -1
vector> dp;
dp.resize(N + 5);
for(int i = 0; i < N + 5; i++)
for(int j = 0; j < M + 5; j++)
dp[i].push_back(-1);
// Stores maximum sum of M elements
sum += mElementsWithMaxSum(matrix, M,
0, dp);
cout << sum;
}
// Driver Code
int main()
{
// Given N
int N = 3;
// Given M
int M = 4;
// Given matrix
vector> matrix = { { 2, 3, 5 },
{ -1, 7 },
{ 8, 10 } };
// Function call
mElementsWithMaxSumUtil(matrix, M, N);
}
// This code is contributed by grand_master
Java
// Java program for the above approach
import java.util.*;
public class GFG {
// Funtion to selct m elements
// having maximum sum
public static long
mElementsWithMaxSum(long[][] matrix,
int M, int block,
long[][] dp)
{
// Base case
if (block == matrix.length)
return 0;
// If precomputed subproblem occurred
if (dp[block][M] != -1)
return dp[block][M];
// Either skip the current row
long ans
= mElementsWithMaxSum(matrix, M,
block + 1, dp);
// Iterate through all the possible
// segments of current row
for (int i = 0;
i < matrix[block].length; i++) {
for (int j = i;
j < matrix[block].length; j++) {
// Check if it is possible to select
// elements from i to j
if (j - i + 1 <= M) {
// Compuete the sum of i to j as
// calculated
ans = Math.max(
ans,
matrix[block][j]
- ((i - 1) >= 0
? matrix[block][i - 1]
: 0)
+ mElementsWithMaxSum(
matrix, M - j + i - 1,
block + 1, dp));
}
}
}
// Store the computed answer and return
return dp[block][M] = ans;
}
// Function to precompute the prefix sum
// for every row of the matrix
public static void
preComputing(long[][] matrix, int N)
{
// Preprocessing to calculate sum from i to j
for (int i = 0;
i < N; i++) {
for (int j = 0;
j < matrix[i].length; j++) {
matrix[i][j]
= (j > 0
? matrix[i][j - 1] : 0)
+ matrix[i][j];
}
}
}
// Utility function to selct m elements having
// maximum sum
public static void
mElementsWithMaxSumUtil(long[][] matrix,
int M, int N)
{
// Preprocessing step
preComputing(matrix, N);
// Initialize dp array with -1
long dp[][] = new long[N + 5][M + 5];
for (long i[] : dp)
Arrays.fill(i, -1);
// Stores maximum sum of M elements
long sum = mElementsWithMaxSum(matrix, M,
0, dp);
// Print the sum
System.out.print(sum);
}
// Driver Code
public static void main(String args[])
{
// Given N
int N = 3;
// Given M
int M = 4;
// Given matrix
long[][] matrix
= { { 2, 3, 5 }, { -1, 7 },
{ 8, 10 } };
// Function Call
mElementsWithMaxSumUtil(matrix, M, N);
}
}
Python3
# Python3 program for the above approach
# Funtion to selct m elements
# having maximum sum
def mElementsWithMaxSum(matrix, M, block, dp):
# Base case
if block == len(matrix):
return 0
# If precomputed subproblem occurred
if (dp[block][M] != -1):
return dp[block][M]
# Either skip the current row
ans = mElementsWithMaxSum(matrix, M,
block + 1, dp)
# Iterate through all the possible
# segments of current row
for i in range(len(matrix[block])):
for j in range(i, len(matrix[block])):
# Check if it is possible to select
# elements from i to j
if (j - i + 1 <= M):
# Compuete the sum of i to j as
# calculated
x = 0
if i - 1 >= 0:
x = matrix[block][i - 1]
ans = max(ans, matrix[block][j] - x +
mElementsWithMaxSum(matrix,
M - j +
i - 1,
block + 1, dp))
# Store the computed answer and return
dp[block][M] = ans
return ans
# Function to precompute the prefix sum
# for every row of the matrix
def preComputing(matrix, N):
# Preprocessing to calculate sum from i to j
for i in range(N):
for j in range(len(matrix[i])):
if j > 0:
matrix[i][j] = matrix[i][j - 1]
return matrix
# Utility function to selct m elements having
# maximum sum
def mElementsWithMaxSumUtil(matrix, M, N):
# Preprocessing step
matrix = preComputing(matrix, N)
sum = 20
# Initialize dp array with -1
dp = [[-1 for i in range(M + 5)]
for i in range(N + 5)]
# Stores maximum sum of M elements
sum += mElementsWithMaxSum(matrix, M, 0, dp)
print(sum)
# Driver Code
if __name__ == '__main__':
# Given N
N = 3
# Given M
M = 4
# Given matrix
matrix = [ [ 2, 3, 5 ],
[ -1, 7 ],
[ 8, 10 ] ]
# Function call
mElementsWithMaxSumUtil(matrix, M, N)
# This code is contributed by mohit kumar 29
C#
// C# program for
// the above approach
using System;
class GFG{
// Funtion to selct m elements
// having maximum sum
public static int mElementsWithMaxSum(int[,] matrix,
int M, int block,
int[,] dp)
{
// Base case
if (block == matrix.GetLength(0))
return 0;
// If precomputed subproblem occurred
if (dp[block, M] != -1)
return dp[block, M];
// Either skip the current row
int ans = mElementsWithMaxSum(matrix, M,
block + 1, dp);
// Iterate through all the possible
// segments of current row
for (int i = 0;
i < GetRow(matrix, block).Length; i++)
{
for (int j = i;
j < GetRow(matrix, block).Length; j++)
{
// Check if it is possible to select
// elements from i to j
if (j - i + 1 <= M)
{
// Compuete the sum of i to j as
// calculated
ans = Math.Max(ans, matrix[block, j] -
((i - 1) >= 0 ?
matrix[block, i - 1] : 0) +
mElementsWithMaxSum(matrix,
M - j + i - 1,
block + 1, dp));
}
}
}
// Store the computed answer and return
return dp[block, M] = ans;
}
// Function to precompute the prefix sum
// for every row of the matrix
public static void preComputing(int[,] matrix,
int N)
{
// Preprocessing to calculate sum from i to j
for (int i = 0; i < N; i++)
{
for (int j = 0;
j < GetRow(matrix, i).Length; j++)
{
matrix[i, j] = (j > 0 ? matrix[i, j - 1] : 0) +
matrix[i, j];
}
}
}
// Utility function to selct
// m elements having maximum sum
public static void mElementsWithMaxSumUtil(int[,] matrix,
int M, int N)
{
// Preprocessing step
preComputing(matrix, N);
// Initialize dp array with -1
int [,]dp = new int[N + 5, M + 5];
for(int i = 0; i < N + 5; i++)
{
for (int j = 0; j < M + 5; j++)
{
dp[i, j] = -1;
}
}
// Stores maximum sum of M elements
int sum = mElementsWithMaxSum(matrix, M,
0, dp);
// Print the sum
Console.Write(sum);
}
public static int[] GetRow(int[,] matrix,
int row)
{
var rowLength = matrix.GetLength(1);
var rowVector = new int[rowLength];
for (var i = 0; i < rowLength; i++)
rowVector[i] = matrix[row, i];
return rowVector;
}
// Driver Code
public static void Main(String []args)
{
// Given N
int N = 3;
// Given M
int M = 4;
// Given matrix
int[,] matrix = {{2, 3, 5},
{-1, 7,0},
{8, 10, 0}};
// Function Call
mElementsWithMaxSumUtil(matrix, M, N);
}
}
// This code is contributed by Princi Singh
输出:
30
时间复杂度: O(N * M)
辅助空间: O(N * M)