题目描述:
给你一个整数数组 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,这是可获得的最大值。
解题思路
在上题中,我们设dp[i][j](true/false)为第一个i奖励后的状态,表示我们是否能得到j分。请注意,dp数组是一个布尔数组。我们只需要每个元素1个比特,所以我们可以使用比特集或类似的东西。我们只需要一个比特的“流”,并应用位操作来通过一个常数因子优化计算。
代码实现
class Solution {
public:
public:
int maxTotalReward(vector<int> &rewardValues)
{
ranges::sort(rewardValues);
rewardValues.erase(unique(rewardValues.begin(), rewardValues.end()), rewardValues.end());
bitset<100000> f{1};
for (int v : rewardValues)
{
int shift = f.size() - v;
// 左移 shift 再右移 shift,把所有 >= v 的比特位置 0
// f |= f << shift >> shift << v;
f |= f << shift >> (shift - v); // 简化上式
}
for (int i = rewardValues.back() * 2 - 1;; i--)
if (f.test(i))
return i;
}
};
标签:下标,比特,int,shift,力扣,奖励,rewardValues,3181,一题
From: https://blog.csdn.net/C_Java_python12/article/details/143252819