【问题标题】:Subset sum with binary numbers二进制数的子集和
【发布时间】:2014-12-26 19:04:53
【问题描述】:

我得到了 X 个长度为 Y 的二进制数,想看看它们加起来是否等于一个特定的总和 K。

我对子集和问题的动态解决方案进行了一些研究;但是,我认为这个具体问题出现了转折。

将两个长度为 Y 的二进制数相加并将总和的长度限制为 Y 有时会从总和中减去 2^(Y)(如果存在溢出)。由于两个二进制数相加有时会导致溢出,比如相加:

10000000000000000000000000000000000000010
10000000000000000000000000000000000000010

将产生总和

00000000000000000000000000000000000000100

因此,在某些情况下,添加数字实际上会降低当前总和。

此刻,我正用头撞墙。任何提示或指针如何攻击这个特定版本的子集和问题?

更新:

我可以使用的内容没有真正的限制。我唯一的目标是产生最快的运行时间,大约 50 个长度为 ~40 的二进制数

【问题讨论】:

  • 为什么数字的表达方式很重要?您所拥有的仍然是子集和问题的某个版本。那么,这里有哪些额外的限制可以使它更快地解决呢?你能有多少个数字?
  • 据我所知,这无关紧要,整数以 2 的幂为模是 ring 而不是 field,但我所知道的子集和算法都不依赖于存在乘法逆元。
  • 使用模 2^(Y+1) 不会破坏标准动态规划算法?
  • 不,但它需要一个长度为 2^Y 的数组(顺便说一句,它不是模 2^Y 吗?)
  • 你是对的,它是 2^Y。但是,在我的平均运行情况下,当 Y = ~40 时,长度为 2^Y 的数组似乎很极端。这是唯一的解决方案吗?

标签: algorithm binary dynamic-programming subset subset-sum


【解决方案1】:

您可以使用中间相遇技术。

  1. 将初始数组分成两半(如果总共有 50 个数字,则为 25 个数字)。

  2. 对于每一半,生成所有可能的子集总和(这需要O(2^n)O(2^n * n) 时间)。 n = 25应该是可行的(n是一半的大小)。

  3. 对于前半部分的每个可能的总和,使用哈希表检查后半部分是否存在适当的总和(使用A + B = target (mod M) 表示B = target - A (mod M) 的事实)。

【讨论】:

  • 这不会导致 O(n^2) 解决方案也需要 O(n^2) 内存吗?也许这是唯一的方法,但它与暴力解决方案相比并没有什么大的进步(只需在 O(n^2) 时间内生成所有可能的子集)。
  • @RasmusJ 这是O(2 ^ (n / 2)) 时间和记忆。比O(2 ^ n)好多了。
猜你喜欢
  • 1970-01-01
  • 2012-11-12
  • 1970-01-01
  • 2014-06-05
  • 2021-06-30
  • 1970-01-01
  • 2016-01-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多