1031. 两个无重叠子数组的最大和 - 力扣(LeetCode)

Solution
这题思路和 2555. 两个线段获得的最多奖品 - 力扣(LeetCode) 基本上一模一样,利用dp的思想先维护一个数组dp,dp[i]表示索引[0...i]范围内符合要求的子数组最大值,然后第二次遍历,维护当前窗口值,再加上这个窗口之前的dp[l-1],选出最大值即可。
需要注意的是这题需要这样做两边,左边first个右边second个,左边second和右边first个,选出其中的最大值即为答案。
cpp
class Solution {
public:
int maxSumTwoNoOverlap(vector<int>& nums, int firstLen, int secondLen) {
int n = nums.size();
vector<int> dp(n + 1, 0);
int l = 0, win = 0;
for (int r = 0; r < n; ++r) {
win += nums[r];
while (r - l + 1 > firstLen) {
win -= nums[l];
l++;
}
dp[r] = (r > 0) ? max(dp[r - 1], win) : win;
}
// for(int i=0;i<n;++i)
// cout<<dp[i]<<" ";
l = 0, win = 0;
int res = 0;
for (int r = 0; r < n; ++r) {
win += nums[r];
while (r - l + 1 > secondLen) {
win -= nums[l];
l++;
}
if (l > 0)
res = max(res, win + dp[l - 1]);
}
l=0,win=0;
for (int r = 0; r < n; ++r) {
win += nums[r];
while (r - l + 1 > secondLen) {
win -= nums[l];
l++;
}
dp[r] = (r > 0) ? max(dp[r - 1], win) : win;
}
l = 0, win = 0;
for (int r = 0; r < n; ++r) {
win += nums[r];
while (r - l + 1 > firstLen) {
win -= nums[l];
l++;
}
if (l > 0)
res = max(res, win + dp[l - 1]);
}
return res;
}
};