【Leetcode】3180. 执行操作可获得的最大总奖励 I——1849
题目
3180. 执行操作可获得的最大总奖励 I
给你一个整数数组
rewardValues,长度为n,代表奖励的值。最初,你的总奖励
x为 0,所有下标都是未标记的。你可以执行以下操作任意次:
从区间
[0, n - 1]中选择一个未标记的下标i。如果
rewardValues[i]大于 你当前的总奖励x,则将rewardValues[i]加到x上(即x = x + rewardValues[i]),并 标记下标i。
以整数形式返回执行最优操作能够获得的最大总奖励。\(1\leq rewardValues.length\leq 2000\)
\(1\leq rewardValues[i]\leq 2000\)
思路
首先可以想到的就是最大的数字一定是需要选定的
证明方法是反证法。假定最后选择的数字不是最大的数字x,那么最大的数字一定是不小于这个x的,因此不选择其他的更多数字,仅仅将x替换为最大的数字也是不差于原始的结果的,因此最后选择的数字一定是最大的数字。
因此,考虑到上述分析最后一次一定是选择最大的数字,那么为了满足题目的条件,那么就需要找到一个组合即他们的和不超过最大的数字。
而考虑到数据的范围,数字的范围不算大,因此考虑将能否选择到该数字作为动态规划的对象。
class Solution:
def maxTotalReward(self, rewardValues: List[int]) -> int:
rewardValues.sort()
dp = [False]*(rewardValues[-1])
dp[0] = True
n = len(rewardValues)
for i in range(n-1):
for j in range(rewardValues[i]):
if rewardValues[i] + j>=rewardValues[-1]: break
dp[rewardValues[i]+j] |= dp[j]
for i in range(rewardValues[-1]-1,-1,-1):
if dp[i]: return i+rewardValues[-1]
return -1
算法时间复杂度为\(O(N^2)\)
接下来展示的是python魅力时刻。
class Solution:
def maxTotalReward(self, nums: List[int]) -> int:
f = 1
for x in sorted(set(nums)):
f |= (f & ((1 << x) - 1))<<x
return f.bit_length()-1

浙公网安备 33010602011771号