给定n个整数的列表,找到大于X的最小子集和

时间:2016-11-30 21:45:41

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

给定数组形式的未排序整数集,找到大于或等于const整数{4 5 8 10 10}的最小子集和。

例如: - 我们的设置为x=15x 所以最小子集和最接近>=x is {5 10}>=x

我只能想到一个简单的算法,它列出了集合的所有子集,并检查子集的总和是否为#include <iostream> #include <atomic> #include <vector> namespace my { template<typename value_type> value_type atomic_add(std::atomic<value_type>& operand, value_type value_to_add) { value_type old = operand.load(std::memory_order_consume); value_type desired = old + value_to_add; while (!operand.compare_exchange_weak(old, desired, std::memory_order_release, std::memory_order_consume)) desired = old + value_to_add; return desired; } } int main() { std::vector<double> vector; for(int i = 0; i < 100; i++) { double a; a = 2.0; vector.push_back(a); } std::atomic<double> d; for(int i = 0; i < vector.size(); i++) my::atomic_add(d, vector[i]); std::cout << d << std::endl; } 和最小值,但是它的指数算法并列出所有子集需要O(2 ^ N )。我可以使用动态编程在多项式时间内解决它吗?

4 个答案:

答案 0 :(得分:2)

如果您的所有数字的总和为S,并且您的目标数字为X,则可以改为这样的问题:您是否可以选择小于或等于的数字的最大子集等于S-X

你有knapsack problem的特殊情况,其中权重和价值是相等的。

这是个坏消息,因为这意味着你的问题是NP难的,但从好的方面来说,你可以使用KP的动态编程解决方案(仍然不是多项式)。或者你可以尝试KP的多项式近似,如果这对你来说足够好了。

答案 1 :(得分:0)

如上所述,这是NP完整的。另一种看待的方式是,如果可以在多项式时间内解决这个问题,那么子集和问题也可以在多项式时间内解决(如果存在解,那将是相同的)。

答案 2 :(得分:0)

我相信其他答案都不正确。您的问题实际上是0-1背包问题(即无重复)的变化形式,solvable in polynomial time with dynamic programming。您只需要按照@biziclop的答案来制定标准即可。

答案 3 :(得分:0)

贪婪的方法如何?

首先,我们以降序对列表进行排序。然后我们递归地弹出排序列表的第一个元素,从x中减去它的值,然后重复直到x为0或更小。

使用伪代码:

sort(array)
current = 0
solution = []
while current < x:
    if len(array) < 0:
        return -1 //no solution possible
    current += array[0]
    solution.append(array.pop(0))
return solution