通过选择 M 个大小为 K 的子数组来最大化子数组和
给定一个包含N个正整数的数组arr和两个整数K和M ,任务是计算M个大小为K的子数组的最大和。
例子:
Input: arr[] = {1, 2, 1, 2, 6, 7, 5, 1}, M = 3, K = 2
Output: 33
Explanation: The three chosen subarrays are [2, 6], [6, 7] and [7, 5] respectively. So, sum: 8 +12 +13 = 33
Input: arr[] = {1, 4, 1, 0, 6, 7, 5, 9}, M = 4,, K = 5
Output: 76
方法:这个问题可以通过预先计算前缀总和直到每个索引i来解决,这将告诉我们从0到i的子数组的总和。现在这个前缀总和可用于查找每个大小为 K 的子数组的总和,使用公式:
Subarray sum from i to j = Prefix sum till j – prefix Sum till i
找到所有子数组和后,选择最大的M个子数组和来计算答案。
要解决此问题,请执行以下步骤:
- 创建一个向量prefixSum ,其中每个节点表示直到该索引的前缀总和,以及另一个向量subarraySum ,以存储大小为K的所有子数组总和。
- 现在,运行从i=K到i=N的循环,并使用公式 subarraySum [iK, i] = prefixSum[i]-prefixSum[iK]计算每个子数组的总和,并将其推入向量subarraySum 。
- 对subarraySum进行降序排序,然后将前M 个元素相加得到答案。
- 根据以上观察打印答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to calculate the maximum
// sum of M subarrays of size K
int maximumSum(vector& arr, int M, int K)
{
int N = arr.size();
vector prefixSum(N + 1, 0);
// Calculating prefix sum
for (int i = 1; i <= N; ++i) {
prefixSum[i] = prefixSum[i - 1]
+ arr[i - 1];
}
vector subarraysSum;
// Finding sum of each subarray of size K
for (int i = K; i <= N; i++) {
subarraysSum.push_back(
prefixSum[i]
- prefixSum[i - K]);
}
sort(subarraysSum.begin(),
subarraysSum.end(),
greater());
int sum = 0;
// Selecting the M maximum sums
// to calculate the answer
for (int i = 0; i < M; ++i) {
sum += subarraysSum[i];
}
return sum;
}
// Driver Code
int main()
{
vector arr = { 1, 4, 1, 0, 6, 7, 5, 9 };
int M = 4, K = 5;
cout << maximumSum(arr, M, K);
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to calculate the maximum
// sum of M subarrays of size K
static int maximumSum(int []arr, int M, int K)
{
int N = arr.length;
int []prefixSum = new int[N + 1];
// Calculating prefix sum
for (int i = 1; i <= N; ++i) {
prefixSum[i] = prefixSum[i - 1]
+ arr[i - 1];
}
Vector subarraysSum = new Vector();
// Finding sum of each subarray of size K
for (int i = K; i <= N; i++) {
subarraysSum.add(
prefixSum[i]
- prefixSum[i - K]);
}
Collections.sort(subarraysSum,Collections.reverseOrder());
int sum = 0;
// Selecting the M maximum sums
// to calculate the answer
for (int i = 0; i < M; ++i) {
sum += subarraysSum.get(i);
}
return sum;
}
// Driver Code
public static void main(String[] args)
{
int[] arr = { 1, 4, 1, 0, 6, 7, 5, 9 };
int M = 4, K = 5;
System.out.print(maximumSum(arr, M, K));
}
}
// This code is contributed by 29AjayKumar
Python3
# python program for the above approach
# Function to calculate the maximum
# sum of M subarrays of size K
def maximumSum(arr, M, K):
N = len(arr)
prefixSum = [0 for _ in range(N + 1)]
# Calculating prefix sum
for i in range(1, N+1):
prefixSum[i] = prefixSum[i - 1] + arr[i - 1]
subarraysSum = []
# Finding sum of each subarray of size K
for i in range(K, N+1):
subarraysSum.append(prefixSum[i] - prefixSum[i - K])
subarraysSum.sort()
sum = 0
# Selecting the M maximum sums
# to calculate the answer
for i in range(0, M):
sum += subarraysSum[i]
return sum
# Driver Code
if __name__ == "__main__":
arr = [1, 4, 1, 0, 6, 7, 5, 9]
M = 4
K = 5
print(maximumSum(arr, M, K))
# This code is contributed by rakeshsahni
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG
{
// Function to calculate the maximum
// sum of M subarrays of size K
static int maximumSum(int []arr, int M, int K)
{
int N = arr.Length;
int []prefixSum = new int[N + 1];
// Calculating prefix sum
for (int i = 1; i <= N; ++i) {
prefixSum[i] = prefixSum[i - 1]
+ arr[i - 1];
}
List subarraysSum = new List();
// Finding sum of each subarray of size K
for (int i = K; i <= N; i++) {
subarraysSum.Add(
prefixSum[i]
- prefixSum[i - K]);
}
subarraysSum.Sort();
subarraysSum.Reverse();
int sum = 0;
// Selecting the M maximum sums
// to calculate the answer
for (int i = 0; i < M; ++i) {
sum += subarraysSum[i];
}
return sum;
}
// Driver Code
public static void Main()
{
int[] arr = { 1, 4, 1, 0, 6, 7, 5, 9 };
int M = 4, K = 5;
Console.Write(maximumSum(arr, M, K));
}
}
// This code is contributed by Samim Hossain Mondal
Javascript
输出
76
时间复杂度: O(N)
辅助空间: O(N)