李恒道 发表于 2024-10-26 02:54:26

3180. 执行操作可获得的最大总奖励 题解

来源于jager大佬的解释

假如数组中最大的元素为k,而最优解中最大的元素为x,那么使用k替换x肯定符合要求,即k肯定大于所选的其他的元素的和,满足题目的要求。由于使用k替换x之后得到了一个更优的解,因此假设错误,从而证明最大的元素k一定在最优解中,否则不是最优解。

根据以上我们可以证明数组一定包含最后一个元素,假设其值为k,则之前的累加和最大为k-1,则整个累加和最大范围为2k-1

我们可以先对数组排序,然后生成一个二维dp表,行为每个数,列为累加和范围

```js
    rewardValues = rewardValues.sort((a, b) => a - b)
    const dp = new Array(rewardValues.length).fill(0)
      .map(() => new Array(rewardValues * 2).fill(0))
```
先考虑边界,首先累加和为0任何数字都可以满足
第一行只有累加和为0以及累加和要求为第一个数字两种状态为真
其他行则存在选和不选两种状态,如果不选则判断从0...i-1是否存在j的累加和
假设数字为k
如果选,则判断0...-1是否存在的累加和
由于存在累加和不得大于该数字,则如果选的话,最大的边界范围不得大于这个边界
而需要的累加和如果小于该数字,则无法选这个数字,只有不选一种选择
可得选数字的范围为[k,2*k)

```js
var maxTotalReward = function (rewardValues) {
    rewardValues = rewardValues.sort((a, b) => a - b)
    const dp = new Array(rewardValues.length).fill(0)
      .map(() => new Array(rewardValues * 2).fill(0))
    dp = true
    dp] = true
    for (let index = 1; index < dp.length; index++) {
      for (let indey = 0; indey < dp.length; indey++) {
            dp = dp
            if (indey >= rewardValues && indey < 2 * rewardValues) {
                dp = dp || dp]
            }
      }
    }
    for (let index = dp.length - 1; index >= 0; index--) {
      if (dp == true) {
            return index
      }
    }
    return 0
};
```
最后我们直接判断最后一个数字,倒叙查找是否存在第一个为真返回即可

## 基础优化

我们可以看到每一行都转移了该上一行的数据,然后判断是否属于该数字的范围,如果属于则判断是否为真,并设置上
那就可以进行状态压缩到一行
需要注意的是遍历k数字的范围需要从大到小,如果从小到大容易出现本行的状态引用问题

```js
var maxTotalReward = function (rewardValues) {
    rewardValues = rewardValues.sort((a, b) => a - b)
    const dp = new Array(rewardValues * 2).fill(false)
    dp = true
    dp] = true
    for (let index = 1; index < rewardValues.length; index++) {
      const rewardValue = rewardValues
      for (let indey = 2 * rewardValues - 1; indey >= rewardValues; indey--) {
            dp = dp || dp
      }
    }
    for (let index = dp.length - 1; index >= 0; index--) {
      if (dp == true) {
            return index
      }
    }
    return 0
};

```

至此就实现了dp的推测和状态压缩

wuxin0011 发表于 2024-10-30 08:52:42

这题周赛第四题没错出,第三题简化版倒是做出了,没想到是 bitset db ,第一次遇到,以后遇到这种题用 python 最方便

```python
f = 1
for x in sorted(set(a)):
    m = f & ( (1 << x) - 1)
    f |= m << x
return f.bit_length() - 1

```
页: [1]
查看完整版本: 3180. 执行操作可获得的最大总奖励 题解