【发布时间】:2019-09-26 07:22:35
【问题描述】:
我正在尝试编写一个 python 算法来执行以下操作。 给定一组正整数S,找出总和最小且大于或等于k的子集。
例如: S = [50, 103, 85, 21, 30] k = 140
子集 = [85, 50, 21](总和 = 146)
初始集合中的数字都是整数,k可以任意大。通常会有大约 100 个号码在集合中。
当然,存在遍历所有可能子集的蛮力解决方案,但这在 O(2^n) 中运行,这是不可行的。有人告诉我这个问题是 NP-Complete 的,但是应该有一种动态编程方法允许它在伪多项式时间内运行,就像背包问题一样,但是到目前为止,尝试使用 DP 仍然会引导我找到解决方案是 O(2^n)。
有没有一种方法可以将 DP 应用于这个问题?如果是这样,怎么做?我发现 DP 很难理解,所以我可能遗漏了一些东西。
非常感谢任何帮助。
【问题讨论】:
-
伪多项式时间方法可以考虑所有可能的值 [0.1, 0.2, ...14.6]。现在从 0.1 开始,构建您可能的解决方案,直到 14.6。要为 14.6 构建解决方案,您可以将结果用于 (0.1, 14.5) 和 (0.2, 14.4) 等等。
-
对数字进行排序。做 DFS 添加最高未使用值并在超过 k 时停止,然后回溯以找到下一个解决方案。当剩余数不能加到 k 时停止。只有 100 深的堆栈,递归解决方案可能工作正常。
标签: algorithm dynamic-programming