Leetcode每日打卡第3天

题目

执行操作可获得的最大总奖励 I

给你一个整数数组 rewardValues,长度为 n,代表奖励的值。

最初,你的总奖励 x 为 0,所有下标都是 未标记 的。你可以执行以下操作 任意次 

  • 从区间 [0, n - 1] 中选择一个 未标记 的下标 i
  • 如果 rewardValues[i] 大于 你当前的总奖励 x,则将 rewardValues[i] 加到 x 上(即 x = x + rewardValues[i]),并 标记 下标 i

以整数形式返回执行最优操作能够获得的 最大 总奖励。

示例 1:

输入:rewardValues = [1,1,3,3]

输出:4

解释:

依次标记下标 0 和 2,总奖励为 4,这是可获得的最大值。

示例 2:

输入:rewardValues = [1,6,4,3,2]

输出:11

解释:

依次标记下标 0、2 和 1。总奖励为 11,这是可获得的最大值。

提示:

  • 1 <= rewardValues.length <= 2000
  • 1 <= rewardValues[i] <= 2000

 思路

动态规划
记 rewardValues 的最大值为 m,因为最后一次操作前的总奖励一定小于等于 m−1,所以可获得的最大总奖励小于等于 2m−1。假设上一次操作选择的奖励值为 x 1 ,那么执行操作后的总奖励 x≥x 1,根据题意,后面任一操作选择的奖励值 x 2 一定都大于 x,从而有 x 2 >x 1 ,因此执行的操作是按照奖励值单调递增的。

根据以上推断,首先将 rewardValues 从小到大进行排序,使用 dp[k] 表示总奖励 k 是否可获得,初始时 dp[0]=1,表示不执行任何操作获得总奖励 0。然后我们对 rewardValues 进行遍历,令当前值为 x,那么对于 k∈[x,2x−1](将 k 倒序枚举),将 dp[k] 更新为 dp[k−x] ∣ dp[k](符号 ∣ 表示或操作),表示先前的操作可以获得总奖励 k−x,那么加上 x 后,就可以获取总奖励 k。最后返回 dp 中可以获得的最大总奖励。

python3代码

class Solution:
    def maxTotalReward(self, rewardValues: List[int]) -> int:
        rewardValues.sort()
        m = rewardValues[-1]
        dp = [0] * (2 * m)
        dp[0] = 1
        for x in rewardValues:
            for k in range(2 * x - 1, x - 1, -1):
                if dp[k - x] == 1:
                    dp[k] = 1
        res = 0
        for i in range(len(dp)):
            if dp[i] == 1:
                res = i
        return res

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值