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

求将整数数组拆分为尽可能多和为X的子数组的算法

解决思路:最大化和为X的子集数量

这个问题本质是带最大化数量约束的多重子集和问题,核心是优先用最少的元素组成符合要求的子集——因为总元素数固定,每个子集用的元素越少,能拆分出的子集总数就越多。结合你的X=12(偶数)的场景,我们可以按以下步骤优化你的方案:

1. 先处理奇数元素的核心约束

因为12是偶数,每个有效子集的奇数个数必须是偶数(0、2、4...)。先统计你数组里的奇数情况:

  • 奇数列表:7(3次)、3(3次)、9(1次)→ 共7个(奇数个)
  • 必然会剩下1个奇数无法使用(7是奇数,无法全部分配到偶数个奇数的子集里),我们要选最优的奇数舍弃,同时最大化已用奇数的子集数量。

优先找两个奇数直接和为12的组合:

  • 3+9=12 → 这是完美的2元素子集,用掉1个3和1个9,剩余奇数:7(3次)、3(2次)→ 共5个(仍为奇数,需再用4个,舍弃1个)

接下来处理剩余4个奇数:

  • 最优选择是拆成两组7+3,搭配1个2补全到12,即7+3+2=12的子集,这样用掉2个7、2个3、2个2,最后剩下1个7无法使用(这是必须舍弃的奇数)。

2. 优先处理偶数的高效组合

对于偶数元素,同样遵循「最少元素组成子集」的原则,优先拆分出更多子集:

  • 2元素组合:6+6=12、8+4=12(优先选这两种,因为每个子集只用2个元素)
  • 3元素组合:6+4+2=12(仅在2元素组合无法覆盖时使用)

你的偶数列表:6(5次)、4(3次)、8(2次)、2(2次)
按优先级处理:

  1. 用2个8和2个4组成2个[8,4]子集,剩余偶数:6(5次)、4(1次)
  2. 用4个6组成2个[6,6]子集,剩余偶数:6(1次)、4(1次)
  3. 剩余的6和4无法凑出12(缺2,但2已被奇数组合用完),只能放弃。

3. 整合最优拆分方案

最终能得到的子集(比你示例的浪费更少元素):

  • [3,9]
  • [7,3,2]
  • [7,3,2]
  • [8,4]
  • [8,4]
  • [6,6]
  • [6,6]

总共7个子集,仅剩余1个7、1个6、1个4无法使用。

通用算法步骤总结

如果以后遇到类似问题,可以按这个流程来:

  1. 统计频率:统计每个元素的出现次数,以及奇数、偶数的总数。
  2. 处理奇偶约束:根据X的奇偶性,确定每个子集的奇数个数要求,计算可使用的奇数总数(若原总数不符合,舍弃最“没用”的奇数,比如无法和其他数凑出X的)。
  3. 优先拆分元素最少的子集:从1元素、2元素到多元素的顺序遍历组合,尽可能多地生成子集(不超过元素剩余频率)。
  4. 回溯调整:如果某一步的组合导致后续剩余元素无法组成更多子集,回溯尝试其他组合(比如若用7+3+2导致剩余偶数浪费,可尝试3+3+6的组合,看是否能让剩余偶数拆分出更多子集)。

这个问题没有绝对的贪心最优解,小规模数组可以用回溯法尝试所有可能,找到子集数量最多的方案;大规模数组则可以用动态规划,定义状态为dp[i][j]表示前i个元素能组成j个子集的最大剩余元素利用率,或者直接记录最大子集数量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:46:10