You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求使数组元素与X按位与和最大的最小X(含K个1比特)

问题分析与解法

你的方法错误原因

你之前的思路(取数组按位或的前K个最高位)忽略了核心逻辑:二进制位的高低不等于它对总和的实际贡献大小。

按位或只能标记数组中是否存在元素在该位为1,但每个位对总和的贡献是「该位为1的元素个数 × 2^位位置」。比如某个高位可能只有少数元素在该位为1,总贡献反而不如一个低位(该位有大量元素为1)。举个实际反例:

  • 数组[8,8,4,4,4,4,4],K=1
  • 按位或结果是12(二进制1100),你的方法会选最高位8,总和是8+8+0+0+0+0+0=16
  • 但实际上选低位4的总和是0+0+4+4+4+4+4=20,显然更大,这时候你的方法就会出错。

简单说,你只看了位的位置高低,没看该位能带来的实际收益,这是核心错误。

更优解法:动态规划贪心组合

我们需要同时满足「总和最大」和「X最小」两个条件,用动态规划可以高效解决,步骤如下:

1. 计算每个位的贡献值

遍历0到30位(覆盖常规整数范围),对每个位i:

  • 统计数组中该位为1的元素数量cnt
  • 计算该位的总贡献score = cnt * (1 << i)
  • 存储每个位的(score, 位位置i)

2. 排序位

按score从高到低排序;如果两个位的score相同,按位位置i从小到大排序(这样后续选择时,相同贡献下优先选低位,能让X更小)。

3. 动态规划选最优组合

定义dp[k]为选k个位时的两个状态:

  • 第一个值:当前最大的总和
  • 第二个值:达到该总和的最小X

状态转移

  • 初始化dp[0] = (0, 0),其他dp[k]初始化为(-无穷大, 无穷大)
  • 遍历每个排序后的位(score, i):
    • 从k = 当前已选最大数量倒序遍历到1:
      • 如果dp[k-1].总和 + score > dp[k].总和:更新dp[k]为(dp[k-1].总和 + score, dp[k-1].X | (1 << i))
      • 如果dp[k-1].总和 + score == dp[k].总和:如果新的X(dp[k-1].X | (1 << i))比当前dp[k].X小,就更新X为更小的那个

最终结果

dp[K].X就是满足所有条件的答案。

示例验证

拿你给的例子Arr=[8,4,2],K=2:

  1. 计算各位置贡献:
    • 位3(8):score=1×8=8
    • 位2(4):score=1×4=4
    • 位1(2):score=1×2=2
  2. 排序后顺序是(8,3), (4,2), (2,1)
  3. 动态规划过程:
    • dp[0]=(0,0)
    • 处理(8,3):dp[1]=(8,8)
    • 处理(4,2):dp[2]=(12, 12)
    • 处理(2,1):无法更新dp[2](总和10<12)
      最终dp[2].X=12,符合预期。

内容的提问来源于stack exchange,提问作者Ramesh Suresh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 16:24:21