🔗 leetcode.com/problems/ma…
题目
- 给一个数组,和一个数字 k
- 求三个不相交的,且长度为 k 的子数组,使得其 sum 最大
- 返回这三个子数组的起始位置的下标,字典序最小的
思路
- dp
- 第一轮 dp,计算并保留到当前位置为止,一个长度为 k 的子数组的最大值,以及对应的起始下标。递推公式为,dp0[i] = max(dp0[i - 1], presum[i] - presum[i - k])
- 第二轮 dp,计算并保留到当前位置为止,两个长度为 k 且不相交的子数组的最大值,以及对应的起始下标。递推公式为 dp1[i] = max(dp1[i - 1], presum[i] - presum[i - k] + dp0[i - k])
- 第三轮 dp,计算并保留到当前位置为止,三个长度为 k 且不相交的子数组的最大值,以及对应的起始下标。递推公式为 dp2[i] = max(dp2[i - 1], presum[i] - presum[i - k] + dp1[i - k])
代码
class Solution {
public:
vector<int> maxSumOfThreeSubarrays(vector<int>& nums, int k) {
vector<int> presum(nums.size())
presum[0] = nums[0]
for (int i = 1
presum[i] = presum[i-1] + nums[i]
}
vector<int> dp0(nums.size())
vector<int> index0(nums.size())
dp0[k - 1] = presum[k - 1]
index0[k - 1] = 0
for (int i = k
if (dp0[i - 1] >= presum[i] - presum[i - k]) {
dp0[i] = dp0[i - 1]
index0[i] = index0[i - 1]
} else {
dp0[i] = presum[i] - presum[i - k]
index0[i] = i - k + 1
}
}
vector<int> dp1(nums.size())
vector<vector<int>> index1(nums.size())
dp1[2* k - 1] = presum[2 * k - 1]
index1[2*k -1] = {0, k}
for (int i = 2*k
if (dp1[i - 1] >= presum[i] - presum[i - k] + dp0[i - k]) {
dp1[i] = dp1[i - 1]
index1[i] = index1[i - 1]
} else {
dp1[i] = presum[i] - presum[i - k] + dp0[i - k]
index1[i] = {index0[i - k], i - k + 1}
}
}
vector<int> dp2(nums.size())
vector<vector<int>> index2(nums.size())
dp2[3*k - 1] = presum[3*k -1]
index2[3*k -1] = {0, k, 2*k}
int maxsum = dp2[3*k - 1]
int index = 3*k -1
for (int i = 3*k
if (dp2[i-1] >= presum[i] - presum[i - k] + dp1[i - k]) {
dp2[i] = dp2[i-1]
index2[i] = index2[i-1]
} else {
dp2[i] = presum[i] - presum[i - k] + dp1[i - k]
index2[i] = {index1[i-k][0], index1[i-k][1], i-k+ 1}
}
if (maxsum < dp2[i]) {
maxsum = dp2[i]
index = i
}
}
return index2[index]
}
}