索引集的特定子集,在数组中具有最小总和

时间:2012-07-31 16:21:58

标签: algorithm

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

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

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

我甚至无法找到一个多项式时间算法。我很感激有关如何解决这个问题的任何想法。

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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


要看到这一点:给出背包大小T和对象大小c[i]的背包问题,请按照问题中的说明撰写问题,例如a[i]==b[i]==c[i]k == sum(c[i]) - T

然后,背包问题的解决方案是S的索引集:

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)

由于对提出的问题的解决方案最小化sum(b[i] indexed by S)超过有效S,sum(c[i] *not* indexed by S)最大化超过有效S,并且是背包问题的最佳解决方案。