689 三个无重叠子数组的最大和(动态规划-递推)

1. 问题描述:

给定数组 nums 由正整数组成,找到三个互不重叠的子数组的最大和。每个子数组的长度为k,我们要使这3*k个项的和最大化。返回每个区间起始索引的列表(索引从 0 开始)。如果有多个结果,返回字典序最小的一个。

示例:

输入: [1,2,1,2,6,7,5,1], 2
输出: [0, 3, 5]
解释: 子数组 [1, 2], [2, 6], [7, 5] 对应的起始索引为 [0, 3, 5]。
我们也可以取 [2, 1], 但是结果 [1, 3, 5] 在字典序上更大。

注意:

nums.length的范围在[1, 20000]之间。
nums[i]的范围在[1, 65535]之间。
k的范围在[1, floor(nums.length / 3)]之间。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-sum-of-3-non-overlapping-subarrays

2. 思路分析:

3. 代码如下:

from typing import List


class Solution:
    def maxSumOfThreeSubarrays(self, nums: List[int], k: int) -> List[int]:
        n = len(nums)
        s = [0] * (n + 1)
        dp = [[0] * 4 for i in range(n + 2)]
        # 前缀和
        for i in range(1, n + 1):
            s[i] = s[i - 1] + nums[i - 1]
        x = n + 1
        # 因为需要求解字典序最小的方案所以逆着递推这样最终才可以一开始字典序最小的方案的下标
        for i in range(n - k + 1, 0, -1):
            for j in range(1, 4):
                dp[i][j] = max(dp[i + 1][j], dp[i + k][j - 1] + s[i + k - 1] - s[i - 1])
                if dp[i][3] >= dp[x][3]: x = i
        # 从前往后求解这样可以求出字典序最小的方案
        y = 3
        res = list()
        while y > 0:
            while dp[x][y] != dp[x + k][y - 1] + s[x + k - 1] - s[x - 1]: x += 1
            res.append(x - 1)
            x += k
            y -= 1
        return res
上一篇:Codeforece-689-div2


下一篇:689期 | 巨无霸的软肋在哪里? - 如何在一个已经拥有巨大存量的强大敌人身边生存下来。