给定一组n个正整数a1,a2,... a3和另一个正整数M,我将找到A的数字的子集,其总和最接近于M.换句话说,我' m试图找到A的子集A',使得绝对值| M - Σa∈A'|最小化,其中[Σa∈A'a]是A'数的总和。我只需返回解决方案子集A'的元素之和,而不报告实际的子集A'。
例如,如果我们将A设为{1,4,7,12}并且M = 15.那么,解决方案子集是A'= {4,12},因此算法只需要返回4 + 12 = 16作为答案。
应该运行问题的动态编程算法 最坏情况下的O(nK)时间,其中K是所有A的总和。
答案 0 :(得分:1)
构建一个大小为n * K的动态编程表,其中
D[i][j] = Can you get sum j using the first i elements ?
您可以使用的递归关系是:D[i][j] = D[i-1][j-a[i]] OR D[i-1][j]
如果您认为可以添加或保留第i个元素,则可以派生此关系。
时间复杂度:O(nK)其中K =所有元素的总和
最后,你迭代你可以获得的整个可能的总和,即j = 1..K的D [n] [j]。哪个最接近M将是你的答案。
答案 1 :(得分:1)
对于动态算法,我们
这里的值集实际上是一个表。
对于这个问题,我们将值DP [i,j]定义为我们是否可以使用前i个元素获得和j的指标。 (1表示是,0表示否)
这里0< = i< = n,0< = j< = K,其中K是A中所有元素的总和
DP [i + 1,j] = 1,if(DP [i,j] == 1 || DP [i,j-A [i + 1]] == 1)
否则,DP [i + 1,j] = 0。
不要忘记在第一时间将表初始化为0。这解决了边界和无关紧要的情况。
计算您想要的值
通过自下而上的实施,您最终可以填写整个表格。
现在,事情变得容易了。您只需要在表中找到与M值最接近的值。
这里,只需要处理DP [n] [j],因为n覆盖了整个集合。找到距离M最近的j,其值为1.
时间复杂度为O(kn),因为你总共迭代k * n次。