给定数组形式的未排序整数集,找到大于或等于const整数{4 5 8 10 10}
的最小子集和。
例如: - 我们的设置为x=15
和x
所以最小子集和最接近>=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 )。我可以使用动态编程在多项式时间内解决它吗?
答案 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