给出整数数组 A
,将该数组分隔为长度最多为 K 的几个(连续)子数组。分隔完成后,每个子数组的中的值都会变为该子数组中的最大值。
返回给定数组完成分隔后的最大和。
示例:
输入:A = [1,15,7,9,2,5,10], K = 3 输出:84 解释:A 变为 [15,15,15,9,10,10,10]
提示:
1 <= K <= A.length <= 500
0 <= A[i] <= 10^6
思路:
因为是连续,所以用dp[i]来表示以A[i]结尾的的题目的解。
对于每个数,都可能变成它前[0, k]范围的数,
比如对于[a0, a1, a2, a3, a4]这个数组,当k = 3时,
a2可能会变成a2, a1, a0。
所以把每种变化的情况考虑进去,用 j 代表子数组的长度从1 到 k + 1循环,
子数组是A[i - (j - 1): i + 1]
用subarray_max这个变量记录子数组的最大值。
class Solution(object):
def maxSumAfterPartitioning(self, A, K):
"""
:type A: List[int]
:type K: int
:rtype: int
"""
dp = [0 for _ in range(len(A))]
for i, x in enumerate(A): #扫描每个数
subarray_max = x
for j in range(1, K + 1): # J 代表当前子数组的长度,包括A[i]; 子数组是A[i - (j - 1): i + 1]
if i - (j - 1) >= 0:#首先至少能向前构成这长度为 J 的子数组,
subarray_max = max(subarray_max, A[i - (j - 1)]) #确保subarray_max是从子数组的最大值
#这么写subarray_max = max(A[i - (j - 1): i + 1]]也可以过,但是很慢
if i - j < 0: # A[i]之前恰好有j - 1个元素,而它们一共组成了长度为J的子数组,相当于当前子数组可以表示为A[:j]
dp[i] = max(dp[i], subarray_max * j)
else:
dp[i] = max(dp[i], dp[i - j] + subarray_max * j)
return dp[-1]