给定一个由N行可变长度组成的二维数组Blocks[][] 。任务是从行的开头或结尾从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)
高效的方法:为了优化上述方法,想法是使用使用 Memoization 的动态规划。请按照以下步骤操作:
- 给定N行和从各行,从第i行选择任何段,从说从左至右。
- 在i个元素的计数第i行是(R – 1 + 1),并进行到下一行。
- 要计算最大总和,请使用 前缀和技术以计算总和。
- 初始化一个二维数组dp[][] ,其中dp[N][M]通过从N行中最多选择M 个元素来存储最大和。
- 考虑以下两种情况:
- 要么跳过当前行。
- 从当前行中选择不超过所选元素数的任何段。
- 考虑以下两种情况:
下面是上述方法的实现:
C++14
// C++ program for the above approach
#include
using namespace std;
// Funtion to select 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 select 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 select 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 select 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 select 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 select 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 select 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 select
// 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
Javascript
30
时间复杂度: O(N * M)
辅助空间: O(N * M)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。