comments | difficulty | edit_url | rating | source | tags | |||
---|---|---|---|---|---|---|---|---|
true |
Hard |
2688 |
Weekly Contest 401 Q4 |
|
You are given an integer array rewardValues
of length n
, representing the values of rewards.
Initially, your total reward x
is 0, and all indices are unmarked. You are allowed to perform the following operation any number of times:
- Choose an unmarked index
i
from the range[0, n - 1]
. - If
rewardValues[i]
is greater than your current total rewardx
, then addrewardValues[i]
tox
(i.e.,x = x + rewardValues[i]
), and mark the indexi
.
Return an integer denoting the maximum total reward you can collect by performing the operations optimally.
Example 1:
Input: rewardValues = [1,1,3,3]
Output: 4
Explanation:
During the operations, we can choose to mark the indices 0 and 2 in order, and the total reward will be 4, which is the maximum.
Example 2:
Input: rewardValues = [1,6,4,3,2]
Output: 11
Explanation:
Mark the indices 0, 2, and 1 in order. The total reward will then be 11, which is the maximum.
Constraints:
1 <= rewardValues.length <= 5 * 104
1 <= rewardValues[i] <= 5 * 104
We define
We consider the
The final answer is
Since
We define a binary number
Observing the state transition equation
Thus, the answer is the position of the highest bit in
The time complexity is rewardValues
array, rewardValues
array, and the integer
class Solution:
def maxTotalReward(self, rewardValues: List[int]) -> int:
nums = sorted(set(rewardValues))
f = 1
for v in nums:
f |= (f & ((1 << v) - 1)) << v
return f.bit_length() - 1
import java.math.BigInteger;
class Solution {
public int maxTotalReward(int[] rewardValues) {
int[] nums = Arrays.stream(rewardValues).distinct().sorted().toArray();
BigInteger f = BigInteger.ONE;
for (int v : nums) {
BigInteger mask = BigInteger.ONE.shiftLeft(v).subtract(BigInteger.ONE);
BigInteger shifted = f.and(mask).shiftLeft(v);
f = f.or(shifted);
}
return f.bitLength() - 1;
}
}
class Solution {
public:
int maxTotalReward(vector<int>& rewardValues) {
sort(rewardValues.begin(), rewardValues.end());
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);
}
for (int i = rewardValues.back() * 2 - 1;; i--) {
if (f.test(i)) {
return i;
}
}
}
};
func maxTotalReward(rewardValues []int) int {
slices.Sort(rewardValues)
rewardValues = slices.Compact(rewardValues)
one := big.NewInt(1)
f := big.NewInt(1)
p := new(big.Int)
for _, v := range rewardValues {
mask := p.Sub(p.Lsh(one, uint(v)), one)
f.Or(f, p.Lsh(p.And(f, mask), uint(v)))
}
return f.BitLen() - 1
}
function maxTotalReward(rewardValues: number[]): number {
rewardValues.sort((a, b) => a - b);
rewardValues = [...new Set(rewardValues)];
let f = 1n;
for (const x of rewardValues) {
const mask = (1n << BigInt(x)) - 1n;
f = f | ((f & mask) << BigInt(x));
}
return f.toString(2).length - 1;
}