【问题标题】:Specific subset of index set with minimum sum in an array数组中总和最小的索引集的特定子集
【发布时间】:2012-07-31 16:21:58
【问题描述】:

您有 2 个数组 a 和 b,每个数组包含 n 个数字。你有一个数字 k。

[n] = 索引集 1...n

我们希望找到[n]的子集S,使得a中S索引的元素总和至少为k,并且b中S索引的元素总和尽可能小。

我什至找不到一个多项式时间算法。对于如何解决此问题的任何想法,我将不胜感激。

【问题讨论】:

  • 这是作业吗?到目前为止,您提出了哪些方法?子集 S 不一定是连续的元素,对吧?
  • 以下类似的问题可能会给你一些想法:stackoverflow.com/questions/8099334/…stackoverflow.com/questions/443712/…
  • 这不是家庭作业。我正在阅读一个关于向玩家分配资源的问题,在特殊情况下会减少这种情况。我现在看到这是 NP 完全的。背包可以在多项式时间内求解,达到任意精度,我们也可以通过对目标值进行二分搜索将其简化为背包。所以,我想这也可以在多项式时间内以任何精度解决,不过我必须验证这一点。

标签: algorithm


【解决方案1】:

这个问题的一般解决方案是 NP 完全的,因为它包含了背包问题。但是,与背包问题一样,您可以使用动态规划建设性地解决它(在“伪多项式时间”中)。


要看到这个:给定一个背包问题,背包大小T 和对象大小c[i],按照你的问题中描述的那样组合一个问题a[i]==b[i]==c[i]k == sum(c[i]) - T

那么,背包问题的解决方案是S中的索引集合not

sum(c[i] *not* indexed by S) == sum(c[i]) - sum(a[i] indexed by S)

T == sum(c[i]) - k

请注意,S 满足背包约束 sum(c[i] *not* indexed by S) <= T 当且仅当问题约束 sum(a[i] indexed by S) >= k 成立。

sum(c[i] *not* indexed by S) == sum(c[i]) - sum(b[i] indexed by S)

由于所提出问题的解决方案在有效 S 上最小化 sum(b[i] indexed by S),因此sum(c[i] *not* indexed by S) 在有效 S 上最大化,并且是背包问题的最优解。

【讨论】:

    【解决方案2】:

    您至少对多项式感兴趣,对吧? 很容易对集合的所有掩码进行指数迭代并检查两个条件(总和 >= k 并比较我们之前在 b 和现在的总和中的值)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-10
      • 1970-01-01
      • 1970-01-01
      • 2013-06-04
      • 1970-01-01
      • 1970-01-01
      • 2018-10-31
      • 2017-08-22
      相关资源
      最近更新 更多