LeetCode-Python-1043. 分隔数组以得到最大和

给出整数数组 A,将该数组分隔为长度最多为 K 的几个(连续)子数组。分隔完成后,每个子数组的中的值都会变为该子数组中的最大值。

返回给定数组完成分隔后的最大和。

 

示例:

输入:A = [1,15,7,9,2,5,10], K = 3
输出:84
解释:A 变为 [15,15,15,9,10,10,10]

 

提示:

  1. 1 <= K <= A.length <= 500
  2. 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]

 

你可能感兴趣的:(Leetcode,DP)