你有2个数组a和b,每个包含n个数字。你有一个数字k。
[n] =索引集1 ... n
我们希望找到[n]的子集S,使得a中由S索引的元素之和至少为k,并且b中由S索引的元素之和尽可能小。
我甚至无法找到一个多项式时间算法。我很感激有关如何解决这个问题的任何想法。
答案 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,并且是背包问题的最佳解决方案。