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

使用FFT求解固定大小无重复子集所有可能和的方法咨询

固定大小无重复子集和的解法说明

你原有思路的错误点

你的推导存在两个核心问题:

  • 覆盖范围不全:你构造的y+x+x只能覆盖「存在一对重复元素,剩余两个元素任意」的情况,但没有覆盖存在多组重复(比如选了两个1和两个2)、三个及以上相同元素的情况,这类冗余组合都会被误算到合法结果里。
  • 容斥逻辑错误:直接相减会出现重复扣除的问题,比如同时满足多类冗余特征的和会被多次减去,导致最终结果出现负值/漏判。而且随着k增大,需要考虑的容斥项数量指数级增长,最终效率远低于常规解法。

已验证的成熟解法

1. 带子集大小维度的分治FFT解法

这是你提到的无固定大小分治FFT方法的扩展,核心思路是引入「所选元素个数」维度做生成函数运算:

  • 每个元素对应二元生成函数 (1 + y * z^{a_i}),其中y的指数代表选的元素个数,z的指数代表子集和的大小。
  • 我们最终需要的是所有元素生成函数乘积中,y^k项对应的所有z的指数,就是固定大小k的所有合法子集和。
  • 具体实现用分治策略:
    1. 把元素集合拆成大小相近的左右两个子集
    2. 分别计算两个子集的生成函数表:对每个子集,存储t从0到min(子集大小, k)的所有z多项式,第t个多项式表示选t个元素时的所有可能和的频率
    3. 合并两个子集的表:对目标选数t,用FFT卷积计算sum_{i=0}^t 左子集第i个多项式 * 右子集第t-i个多项式,超过k的项直接丢弃减少计算量
  • 复杂度:设所有元素总和为S,总复杂度为O(k S log S log N),属于伪多项式复杂度,在k不大、S不超过1e5的场景下效率很高。

2. Bitset优化动态规划

如果元素都是正整数,且S在1e6以内,这是实现最简单、运行速度最快的方案:

  • 定义dp[i]为一个二进制向量,第j位为1表示选i个元素可以凑出和为j
  • 初始状态dp[0][0] = 1
  • 遍历每个元素a,逆序更新i从k到1:dp[i] = dp[i] | (dp[i-1] << a)
  • 最终dp[k]中所有为1的位对应的数值就是所有合法子集和
  • 复杂度:O(N k S / w),其中w是机器字长(通常为64),因为位运算可以并行,实际运行速度通常比FFT方案更快,且没有FFT的浮点精度问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 00:48:03