两个无重叠子数组的最大和
1031. 两个无重叠子数组的最大和 - 力扣(LeetCode)
Solution
这题思路和 2555. 两个线段获得的最多奖品 - 力扣(LeetCode) 基本上一模一样,利用dp的思想先维护一个数组dp,dp[i]表示索引[0...i]范围内符合要求的子数组最大值,然后第二次遍历,维护当前窗口值,再加上这个窗口之前的dp[l-1],选出最大值即可。
需要注意的是这题需要这样做两边,左边first个右边second个,左边second和右边first个,选出其中的最大值即为答案。
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;}
};