题目
给你一个整数数组 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 <= 20001 <= 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
1779

被折叠的 条评论
为什么被折叠?



