给定一个大小为N的数组arr[]和一个整数K ,任务是通过从数组中删除最多K 个元素来找到最大子数组和。
例子:
Input: arr[] = { -2, 1, 3, -2, 4, -7, 20 }, K = 1
Output: 26
Explanation:
Removing arr[5] from the array modifies arr[] to { -2, 1, 3, -2, 4, 20 }
Subarray with maximum sum is { 1, 3, -2, 4, 20 }.
Therefore, the required output is 26.
Input:arr[] = { -1, 1, -1, -1, 1, 1 }, K=2
Output: 3
Explanation:
Removing arr[2] and arr[3] from the array modifies arr[] to { – 1, 1, 1, 1}
Subarray with maximum sum is { 1, 1, 1 }.
Therefore, the required output is 3.
方法:该问题可以使用动态规划解决。这个想法是使用 Kadane 算法的概念。请按照以下步骤解决问题:
- 遍历数组arr[]并且对于每个数组元素都需要执行以下两个操作:
- 从子数组中删除当前数组元素。
- 在子数组中包含当前数组元素。
- 因此,求解该问题的递推关系如下:
mxSubSum(i, j) = max(max(0, arr[i] + mxSubSum(i – 1, j)), mxSubSum(i – 1, j – 1))
i: Stores index of array element
j: Maximum count of elements that can be removed from the subarray
mxSubSum(i, j): Return maximum subarray sum from the subarray { arr[i], arr[N – 1] } by removing K – j array elements.
- 初始化一个二维数组,比如dp[][] ,以存储上述递推关系的重叠子问题。
- 使用记忆填充dp[][]数组。
- 从 dp[][] 数组中找到最大元素,比如res 。
- 初始化一个变量,比如Max ,以存储数组arr[] 中存在的最大元素。
- 如果所有数组元素都是负数,则更新res = max(res, Max) 。
- 最后,打印res作为所需答案。
下面是上述方法的实现:
C++
// C++ program to implement
// the above approach
#include
using namespace std;
#define M 100
// Function to find the maximum subarray
// sum greater than or equal to 0 by
// removing K array elements
int mxSubSum(int i, int* arr,
int j, int dp[][M])
{
// Base case
if (i == 0) {
return dp[i][j] = max(0, arr[i]);
}
// If overlapping subproblems
// already occurred
if (dp[i][j] != -1) {
return dp[i][j];
}
// Include current element in the subarray
int X = max(0, arr[i]
+ mxSubSum(i - 1, arr, j, dp));
// If K elements already removed
// from the subarray
if (j == 0) {
return dp[i][j] = X;
}
// Remove current element from the subarray
int Y = mxSubSum(i - 1, arr, j - 1, dp);
return dp[i][j] = max(X, Y);
}
// Utility function to find the maximum subarray
// sum by removing at most K array elements
int MaximumSubarraySum(int n, int* arr, int k)
{
// Stores overlapping subproblems
// of the recurrence relation
int dp[M][M];
// Initialize dp[][] to -1
memset(dp, -1, sizeof(dp));
mxSubSum(n - 1, arr, k, dp);
// Stores maximum subarray sum by
// removing at most K elements
int res = 0;
// Calculate maximum element
// in dp[][]
for (int i = 0; i < n; i++) {
for (int j = 0; j <= k; j++) {
// Update res
res = max(res, dp[i][j]);
}
}
// If all array elements are negative
if (*max_element(arr, arr + n) < 0) {
// Update res
res = *max_element(arr, arr + n);
}
return res;
}
// Driver Code
int main()
{
int arr[] = { -2, 1, 3, -2, 4, -7, 20 };
int K = 1;
int N = sizeof(arr) / sizeof(arr[0]);
cout << MaximumSubarraySum(N, arr, K) << endl;
return 0;
}
Java
// Java program to implement
// the above approach
import java.util.*;
class GFG{
static final int M = 100;
// Function to find the maximum subarray
// sum greater than or equal to 0 by
// removing K array elements
static int mxSubSum(int i, int []arr,
int j, int dp[][])
{
// Base case
if (i == 0) {
return dp[i][j] = Math.max(0, arr[i]);
}
// If overlapping subproblems
// already occurred
if (dp[i][j] != -1) {
return dp[i][j];
}
// Include current element in the subarray
int X = Math.max(0, arr[i]
+ mxSubSum(i - 1, arr, j, dp));
// If K elements already removed
// from the subarray
if (j == 0)
{
return dp[i][j] = X;
}
// Remove current element from the subarray
int Y = mxSubSum(i - 1, arr, j - 1, dp);
return dp[i][j] = Math.max(X, Y);
}
// Utility function to find the maximum subarray
// sum by removing at most K array elements
static int MaximumSubarraySum(int n, int []arr, int k)
{
// Stores overlapping subproblems
// of the recurrence relation
int [][]dp = new int[M][M];
// Initialize dp[][] to -1
for (int i = 0; i < M; i++)
for (int j = 0; j < M; j++)
dp[i][j] = -1;
mxSubSum(n - 1, arr, k, dp);
// Stores maximum subarray sum by
// removing at most K elements
int res = 0;
// Calculate maximum element
// in dp[][]
for (int i = 0; i < n; i++) {
for (int j = 0; j <= k; j++) {
// Update res
res = Math.max(res, dp[i][j]);
}
}
// If all array elements are negative
if (Arrays.stream(arr).max().getAsInt() < 0) {
// Update res
res = Arrays.stream(arr).max().getAsInt();
}
return res;
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { -2, 1, 3, -2, 4, -7, 20 };
int K = 1;
int N = arr.length;
System.out.print(MaximumSubarraySum(N, arr, K) +"\n");
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 program to implement
# the above approach
M = 100
# Function to find the maximum subarray
# sum greater than or equal to 0 by
# removing K array elements
def mxSubSum(i, arr, j):
global dp
# Base case
if (i == 0):
dp[i][j] = max(0, arr[i])
return dp[i][j]
# If overlapping subproblems
# already occurred
if (dp[i][j] != -1):
return dp[i][j]
# Include current element in the subarray
X = max(0, arr[i] + mxSubSum(i - 1, arr, j))
# If K elements already removed
# from the subarray
if (j == 0):
dp[i][j] = X
return X
# Remove current element from the subarray
Y = mxSubSum(i - 1, arr, j - 1)
dp[i][j] = max(X, Y)
return dp[i][j]
# Utility function to find the maximum subarray
# sum by removing at most K array elements
# Utility function to find the maximum subarray
# sum by removing at most K array elements
def MaximumSubarraySum(n, arr, k):
mxSubSum(n - 1, arr, k)
# Stores maximum subarray sum by
# removing at most K elements
res = 0
# Calculate maximum element
# in dp[][]
for i in range(n):
for j in range(k + 1):
# Update res
res = max(res, dp[i][j])
# If all array elements are negative
if (max(arr) < 0):
# Update res
res = max(arr)
return res
# Driver Code
if __name__ == '__main__':
dp = [[-1 for i in range(100)] for i in range(100)]
arr = [-2, 1, 3, -2, 4, -7, 20]
K = 1
N = len(arr)
print(MaximumSubarraySum(N, arr, K))
# This code is contributed by mohit kumar 29
C#
// C# program to implement
// the above approach
using System;
using System.Collections;
class GFG{
static int M = 100;
// Function to find the maximum subarray
// sum greater than or equal to 0 by
// removing K array elements
static int mxSubSum(int i, int []arr,
int j, int [,]dp)
{
// Base case
if (i == 0)
{
return dp[i, j] = Math.Max(0, arr[i]);
}
// If overlapping subproblems
// already occurred
if (dp[i, j] != -1)
{
return dp[i, j];
}
// Include current element in the subarray
int X = Math.Max(0, arr[i] +
mxSubSum(i - 1, arr, j, dp));
// If K elements already removed
// from the subarray
if (j == 0)
{
return dp[i, j] = X;
}
// Remove current element from the subarray
int Y = mxSubSum(i - 1, arr, j - 1, dp);
return dp[i, j] = Math.Max(X, Y);
}
// Utility function to find the maximum subarray
// sum by removing at most K array elements
static int MaximumSubarraySum(int n, int []arr, int k)
{
// Stores overlapping subproblems
// of the recurrence relation
int [,]dp = new int[M, M];
// Initialize dp[,] to -1
for(int i = 0; i < M; i++)
for(int j = 0; j < M; j++)
dp[i, j] = -1;
mxSubSum(n - 1, arr, k, dp);
// Stores maximum subarray sum by
// removing at most K elements
int res = 0;
// Calculate maximum element
// in dp[,]
for(int i = 0; i < n; i++)
{
for(int j = 0; j <= k; j++)
{
// Update res
res = Math.Max(res, dp[i, j]);
}
}
Array.Sort(arr);
// If all array elements are negative
if (arr[n - 1] < 0)
{
// Update res
res = arr[n - 1];
}
return res;
}
// Driver Code
public static void Main(String[] args)
{
int []arr = { -2, 1, 3, -2, 4, -7, 20 };
int K = 1;
int N = arr.Length;
Console.WriteLine(MaximumSubarraySum(N, arr, K));
}
}
// This code is contributed by AnkThon
Javascript
26
时间复杂度: O(N * K)
辅助空间: O(N * K)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。