[LeetCode] Maximum Sum of M Non-Overlapping Subarrays I

3956. Maximum Sum of M Non-Overlapping Subarrays I

You are given an integer array nums of length n, and three integers m, l, and r.

Your task is to select at least one and at most m non-overlapping subarrays from nums such that:

  • Each selected subarray has a length between [l, r] (inclusive).
  • The total sum of all selected subarrays is maximized.

Return the maximum total sum you can achieve.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

class Solution {
pair<long long, int> helper(vector<int>& nums, vector<long long>& pre, long long m, long long l, long long r,long long cost) {
int n = nums.size();
vector<long long> dp(n + 1);
vector<int> cnt(n + 1);
deque<int> dq;

auto val = [&](int i) {
return dp[i] - pre[i];
};

auto bad = [&](int a, int b) {
long long va = val(a);
long long vb = val(b);

if (va != vb) return va < vb;
return cnt[a] <= cnt[b];
};

for (int i = l; i <= n; i++) {
int add = i - l;

while (!dq.empty() and bad(dq.back(), add)) dq.pop_back();
dq.push_back(add);

while (!dq.empty() && dq.front() < i - r) dq.pop_front();

dp[i] = dp[i - 1];
cnt[i] = cnt[i - 1];

if (!dq.empty()) {
long long take = val(dq.front()) + pre[i] - cost;
int takeCnt = cnt[dq.front()] + 1;

if (take > dp[i] or (take == dp[i] and takeCnt > cnt[i])) {
dp[i] = take;
cnt[i] = takeCnt;
}
}
}

return {dp[n], cnt[n]};
}
public:
long long maximumSum(vector<int>& nums, int m, int l, int r) {
long long n = nums.size(), res = LLONG_MIN;
vector<long long> pre(n + 1);
for (int i = 0; i < n; i++) {
pre[i + 1] = pre[i] + nums[i];
}
{
multiset<long long> ms;
for(int i = n - l; i >= 0; i--) {
ms.insert(pre[i+l]);
res = max(res, *prev(end(ms)) - pre[i]);
if(i + r <= n) ms.erase(ms.find(pre[i+r]));
}
}
auto zero = helper(nums, pre, m, l, r, 0);
if(!zero.second) return res;
if(zero.second <= m) return zero.first;
long long le = 0, ri = 1e18;
while (le <= ri) {
long long mid = le + (ri - le) / 2;
auto [v, c] = helper(nums, pre, m, l, r, mid);

if (c > m) {
le = mid + 1;
} else {
ri = mid - 1;
}
}

auto [v, c] = helper(nums, pre, m, l, r, ri);

return v + ri * 1LL * m;
}
};
Author: Song Hayoung
Link: https://songhayoung.github.io/2026/09/04/PS/LeetCode/maximum-sum-of-m-non-overlapping-subarrays-i/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.