欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > 【0-1背包hard】力扣3181. 执行操作可获得的最大总奖励 II

【0-1背包hard】力扣3181. 执行操作可获得的最大总奖励 II

2025/2/5 15:53:58 来源:https://blog.csdn.net/sjsjs11/article/details/141749358  浏览:    关键词:【0-1背包hard】力扣3181. 执行操作可获得的最大总奖励 II

给你一个整数数组 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,这是可获得的最大值。

在这里插入图片描述
0-1背包

class Solution {
public:int maxTotalReward(vector<int>& rewardValues) {int m = ranges::max(rewardValues);if (ranges::find(rewardValues, m - 1) != rewardValues.end()) {return m * 2 - 1;}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;//f |= f<<shift>>shift<<v;f |= f<<shift>>(shift-v);}for(int i = m*2-1;;i--){if(f.test(i)){return i;}}}
};

这道题目本质是0-1背包的变种。首先先进行排序,然后使用erase + unique的方法来使得数组rewardValues变成一个升序的不重复的数组。

接下来定义一个bitset,他的大小由题目条件限制可以得出,由于bitset最右边是第0个比特位,要初始化为1,所以bitset的大小就是100000。

f <<shift>>shift的作用就是将>=v的比特位置0,然后更新f的时候,要包含两种情况,一种是不选择v,则f和之前一样,如果选择v,那么就将低v位向左移动v位,然后取或。

最后返回最高位的比特位的位置即可。

然后在开头可以进行优化,如果能找到m-1这个元素,那么则直接返回m*2-1,不用接下来的运算

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com