无法理解最长增加子序列的算法

时间:2017-04-05 13:31:38

标签: algorithm dynamic-programming

我已经通过许多在线资源来了解问题如何具有最佳子结构,但都是徒劳的,我无法理解在这种情况下通过解决较小的子问题如何获得解决方案。

如果任何解释有助于理解解决方案,我将感激不尽。

到目前为止,我理解最佳子结构属性如下:

示例性因素:

因此,对于因子40,事实(40),我们可以通过计算事实(39)* 40来实现解决方案,依此类推39,38 .... 2 ans,因为我们知道事实(2)是2我们可以用同样的方式从2到40建立它。

但我无法与LIS联系,请帮助

对解决方案的完整解释很不错,不包括重叠的子问题,因为这可以在以后处理。

感谢。

2 个答案:

答案 0 :(得分:1)

针对序列(问题)的LIS可以通过对较小序列(子问题)使用LIS来解决,这就是为什么已知具有最佳子结构的原因。

让我尝试解释该示例的工作方式。让我们随机选择10个数字:

[21,24,13,48,-3,41,36,8,-10,22]

我们将使用较小的问题(较小的序列)来解决此问题。子问题的定义是这种情况是“以给定元素结尾的最长的递增数字序列是什么?”

重要的是要了解此子问题与LIS不同-该子问题对原始问题有更严格的定义(LIS不必在最后一个元素结束)。

出于可读性考虑,我将其称为“以给定元素结尾的最长的递增子序列”:LIS *。

LIS *和LIS之间的关系是LIS占LIS *的Max

让我们从一个数字开始。

[21]

以21结尾的最长递增子序列是什么?它只是“ 21”。因此,我们序列的长度为1。

序列:[21]
LIS *:1
LIS:1

现在,对于第二个元素(24),根据定义,我们需要针对已经解决的问题使用解决方案。我们将LIS用于第一个元素,检查第二个元素是否更大(a[i] > a[j),以及是否LIS[j]+1 > LIS[i]。以24结尾的最长递增序列是'21,24',长度为2。

序列:[21,24]
LIS *:2
LIS:2

让我们考虑第三个要素(13)。以13结尾的最长递增子序列是什么?好吧,13小于21且小于24,因此对于任何先前元素都不满足条件a[i] > a[j]。因此以13结尾的最长递增子序列仅为'13',长度为1。序列21、24、13的LIS仍为2。

序列:[21,24,13]
LIS *:1
LIS:2

让我们看一下第4个元素(48)。我们知道3长度序列的解为2。我们可以找到满足条件a[i] > a[j]LIS[j]+1 > LIS[i]的先前元素(24)。我们知道前一个元素(较小问题)的解决方案是2,因此这里的解决方案将是2 + 1 = 3。

序列:[21,24,13,48]
LIS *:3
LIS:3

我们为所有后续元素重复逻辑。

序列:[21、24、13、48,-3、41、36、8,-10、22]
LIS *:1 2 3 1 3 3 2 3 1 2 3 LIS:1 2 2 2 3 3 3 3 3 3 3 3

如您所见,可以通过查看子问题(较小的序列)来获得原始问题(长序列)的解决方案,因此已知该问题具有最佳的子结构。

答案 1 :(得分:0)

在考虑最优子结构之前,您需要确定LIS情况下的子问题。让我们使用这个定义:

  

在长度为a[N]的数组N中,子问题LIS[k]是从初始索引中找到最长增长子序列的长度,该索引正好在元素{{1}处结束}。

了解这里的差异非常重要:a[k] 是第一个LIS[k]元素上的LIS解决方案;所有kMax(LIS[i])的{​​{1}}为i。它是在特定元素处结束的最长增长子序列的长度。

有了这个定义,很容易构建LIS的解决方案:

  • 每个k最多i
  • N设为1(在最坏的情况下,数字是一个的后续部分)
  • LIS[i]搜索LIS[j]i-1,包括ja[i] > a[j]LIS[j]+1 > LIS[i]

很容易看出,上述算法构建了LIS[i]解决方案的解决方案,为O(i)中LIS[j]以下的所有j提供了子问题i的解决方案。由于我们可以从解决问题到k子问题构建k-1问题的解决方案,因此问题具有最佳子结构。

注意:以上内容可以通过二进制搜索进一步优化。然而,关于子问题和最优子结构的推理仍然是相同的。