Leetcode2919. 使数组变美的最小增量运算数 记忆化搜索

1.题目描述

给你一个下标从 0 开始、长度为 n 的整数数组 nums ,和一个整数 k 。

你可以执行下述 递增 运算 任意 次(可以是 0 次):

  • 从范围 [0, n - 1] 中选择一个下标 i ,并将 nums[i] 的值加 1 。

如果数组中任何长度 大于或等于 3 的子数组,其 最大 元素都大于或等于 k ,则认为数组是一个 美丽数组 。

以整数形式返回使数组变为 美丽数组 需要执行的 最小 递增运算数。

子数组是数组中的一个连续 非空 元素序列。


2.解题思路

记忆化搜索

题目要求【任何长度大于或等于3】的子数组【>=k】,那么等价于要求任何长度大于3的子数组,包含至少一个>=k的数。进一步抽象化:选一个【子序列】,子序列的所有元素都需要变成>=k的数,子序列的相邻元素不能间隔太大,相邻元素的下标差要<=3。

定义

dfs(i, j)表示现在要处理nums[0]到nums[i]这段子数组,并且num[i]右边有j个没有变大的数。

比如这个例子,对于当前i:右边只有一个没有变大的数

利用这种定义,我们就能从dfs(i, j)转移到i - 1

从后往前枚举

选:`dfs[i][j] = dfs(i - 1, 0) + max(k - nums[i], 0)`

不选:`if (j < 2) dfs[i][j] = dfs(i - 1, j + 1)`,对于i - 1,右边多一个不选的数。前提是j < 2,如果i - 1右边已经有2个没有选的数,那么下一个就必须选,不能不选。

递归边界

当 i < 0 的时候,返回0

递归入口

dfs(n - 1, 0)


3.AC_code

class Solution:
    def minIncrementOperations(self, nums: List[int], k: int) -> int:
        n = len(nums)
        @cache
        def dfs(i: int, j: int):
            if i < 0:
                return 0
            res = dfs(i - 1, 0) + max(k - nums[i], 0)
            if j < 2: 
                res = min(res, dfs(i - 1, j + 1))
            return res
        return dfs(n - 1, 0)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值