【力扣roadmap】3469. 移除所有数组元素的最小代价

21 阅读1分钟

题目描述

image.png

思路

虽然从逻辑上,这个数组的长度会变化,乍一看会影响下标,从而影响dp求解。但是不用担心,这个题目可以看成,每次操作都会剩余一个元素,再与接下来的字符串进行操作。 比如,你操作了最开始的三个元素,无论你是删除了第0个和第1个还是第0个和第2个还是第1个和第2个,你一定会剩下一个元素,再与剩余元素结合成新数组,进行接下来的操作。

假设dp[i][remain]dp[i][remain]表示剩余字符串的开始下标是ii,前面操作剩余的元素大小是remain。接下来将考虑remain, nums[i], nums[i+1]三个元素,谁去谁留(注意,不一定是删除最大的两个留最小的,这一点你可以从题目给的示例中发现)。我们将上面的三个元素从小到大排列,分别是a,b,c

我们分情况讨论:

  • 情况1: 删除a和b, 保留最大的c, 那么此时的代价可以表示为 dp[i+2][c] + b

  • 情况2: 删除b和c, 保留最小的a, 那么此时的代价可以表示为 dp[i+2][a] + c

  • 情况3: 删除a,c,只保留b, 那么此时的代价可以表示为 dp[i+2][b] + c。 但是这种情况一定不如情况2。

代码

class Solution:
    def minCost(self, nums: List[int]) -> int:
        
        n = len(nums)
        @cache
        def dfs(i : int , remain: int) -> int :

            if i == n :
                return remain
            if i == n-1:
                return max(nums[n-1] , remain)
            a , b, c = sorted([remain,nums[i],nums[i+1]])
            return min(dfs(i+2,a) + c , dfs(i+2,c) + b) 
        
        return dfs(1 , nums[0])