题目描述
思路
虽然从逻辑上,这个数组的长度会变化,乍一看会影响下标,从而影响dp求解。但是不用担心,这个题目可以看成,每次操作都会剩余一个元素,再与接下来的字符串进行操作。 比如,你操作了最开始的三个元素,无论你是删除了第0个和第1个还是第0个和第2个还是第1个和第2个,你一定会剩下一个元素,再与剩余元素结合成新数组,进行接下来的操作。
假设表示剩余字符串的开始下标是,前面操作剩余的元素大小是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])