描述
给定一个数组nums和一个数k,求把数组分成k个子数组时和最大的值。
思路
dp。
当数组长度等于k时,全部选。
当数组长度小于k时,无解。
当数组长度大于k时,
#local/global[i][j]表示前i个元素分成j个子组时和最大值
#local[i][j]时第i个必选,为了如果第i+1个想跟前面的元素一组时可以拼一起
#global[i][j]时第i个不一定选
# local[i-1][j]表示nums[i]加入上一个子数组成为一部分
# global[i-1][j-1]表示nums[i]重新开始一个新的子数组
local[i][j] = max(local[i - 1][j], globa[i - 1][j - 1]) + nums[i - 1]
globa[i][j] = max(globa[i - 1][j], local[i][j])
from typing import (
List,
)
class Solution:
"""
@param nums: A list of integers
@param k: An integer denote to find k non-overlapping subarrays
@return: An integer denote the sum of max k non-overlapping subarrays
"""
def maxSubArray(self, nums, k):
n = len(nums)
if n < k: # 当数组长度小于k时无解
return 0
local = [[0] * (k + 3) for _ in range(n + 3)]
globa = [[0] * (k + 3) for _ in range(n + 3)]
for i in range(1, n + 1):
for j in range(1, min(k,i)+1):
if i == j:
local[i][j] = local[i - 1][j - 1] + nums[i - 1]
globa[i][j] = globa[i - 1][j - 1] + nums[i - 1]
else:
# local[i-1][j]表示nums[i]加入上一个子数组成为一部分
# global[i-1][j-1]表示nums[i]重新开始一个新的子数组
local[i][j] = max(local[i - 1][j], globa[i - 1][j - 1]) + nums[i - 1]
globa[i][j] = max(globa[i - 1][j], local[i][j])
return globa[n][k]