3180. 执行操作可获得的最大总奖励 I(1849)
给你一个整数数组 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
解答:背包没有限制但有物品添加条件限制,其中每个物品价值为1,求最大价值和
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Solution { public int maxTotalReward(int[] rewardValues) { int nums[] = Arrays.stream(rewardValues).toArray(); int n = nums.length; Arrays.sort(nums); int MAX = nums[n-1]*2; int f[][] = new int[n+1][MAX], res = 0; f[0][0] = 1; for (int i = 0; i < n; i++) { int value = nums[i]; for (int j = 0; j < MAX; j++) { f[i+1][j] = f[i][j]; if (j-value >= 0 && value > j-value) { f[i+1][j] = Math.max(f[i+1][j], f[i][j-value]); } if (f[i+1][j] == 1) res = Math.max(res, j); } } return res; } }
|
优化:减少一个维度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Solution { public int maxTotalReward(int[] rewardValues) { int nums[] = Arrays.stream(rewardValues).toArray(); int n = nums.length; Arrays.sort(nums); int MAX = nums[n-1]*2; int f[] = new int[MAX], res = 0; f[0] = 1; for (int i = 0; i < n; i++) { int value = nums[i]; for (int j = 0; j < MAX; j++) { if (j-value >= 0 && value > j-value) { f[j] = Math.max(f[j], f[j-value]); } if (f[j] == 1) res = Math.max(res, j); } } return res; } }
|