找到低于或等于某个值的最大子序列

时间:2013-10-13 18:30:09

标签: algorithm recursion dynamic-programming

我正在学习动态编程,而且我在理解更复杂的问题时遇到了很多麻烦。当遇到问题时,我被教导要找到一个递归算法,记住递归算法,然后创建一个迭代的自下而上版本。几乎每一步都有问题。就递归算法而言,我编写了不同的方法来进行递归算法,但只有一种方法通常最适合用于动态编程,我无法区分递归算法的哪些方面使记忆更容易。在记忆方面,我不明白哪些值用于索引。为了转换为自下而上的版本,我无法确定填充数组/双数组的顺序。

这就是我的理解: - 应该可以将主要问题分解为子问题

就上述问题而言,我提出了一个具有以下重要代码行的递归算法:

int optionOne = values[i] + find(values, i+1, limit - values[i]);
int optionTwo = find(values, i+1, limit);

如果我不清楚或者这不是正确的qa网站,请告诉我。

编辑:

示例:给定数组x:[4,5,6,9,11]和最大值m:20

x小于或等于m的最大子序列为[4,5,11]为4 + 5 + 11 = 20

1 个答案:

答案 0 :(得分:1)

我认为这个问题是NP难的,这意味着除非P = NP,否则没有多项式时间算法来解决问题。

从子集求和问题到这个问题的简单减少。在subset-sum中,您将获得一组n个数字和一个目标数k,并希望确定这些数字的子集是否恰好合计为k。您可以使用求解器解决子集求和,如下所示:在集合中创建数字数组,并找到其总和小于或等于k的最大子序列。如果这恰好与k相加,则该集合具有加起来为k的子集。否则,它没有。

这种减少需要多项式时间,所以因为子集和是NP难的,所以你的问题也是NP难的。因此,我怀疑是否存在多项式时间算法。

那就是说 - 子集和的伪多项式时间算法是described on Wikipedia。该算法在两个变量中使用DP并且不是严格的多项式时间,但它可能适用于您的情况。

希望这有帮助!