找到增长最长的子序列(LIS)

时间:2011-10-27 15:22:48

标签: dynamic-programming

鉴于A = {1,4,2,9,7,5,8,2},找到LIS。显示填充的动态编程表以及如何找到解决方案。

我的书没有涵盖LIS所以我对如何开始有点迷失。对于DP表,我做了类似于最长公共子序列的事情。如何开始这方面的任何帮助将非常感激。

2 个答案:

答案 0 :(得分:1)

LIS与LCS之间存在非常密切的关系。

http://en.wikipedia.org/wiki/Longest_increasing_subsequence

这篇文章很好地解释了我的想法。基本上这个想法是,你可以将一个问题减少到另一个(在许多涉及动态编程的情况下就是这种情况)。

答案 1 :(得分:0)

关于这个主题已经有很多答案,但这是我的演练,我将此网站视为未来后代的答案存储库,这只是为了在我自己完成工作时提供额外的见解。

最长的增加子序列(LIS)问题是找到给定序列的最长子序列的长度,使得所有元素都是 子序列按递增顺序排序。例如,

的LIS长度
{ 10, 22, 9, 33, 21, 50, 41, 60, 80 } is 6 and LIS is {10, 22, 33, 50, 60, 80}.

S[pos]定义为结束长度为pos的递增序列的最小整数。

现在迭代输入集的每个整数X并执行以下操作:

如果X> S中的最后一个元素,然后将X附加到S的末尾。这必然意味着我们找到了一个新的最大LIS。

否则找到S中的最小元素,即> =而不是X,并将其更改为X.因为S在任何时候都被排序,所以可以找到该元素 在log(N)中使用二进制搜索。

总运行时间 - N个整数和每个整数的二进制搜索 - N * log(N)= O(N log N)

现在让我们举一个真实的例子:

整数组:2 6 3 4 1 2 9 5 8

步骤:

0. S = {} - Initialize S to the empty set
1. S = {2} - New largest LIS
2. S = {2, 6} - 6 > 2 so append that to S
3. S = {2, 3} - 6 is the smallest element > 3 so replace 6 with 3
4. S = {2, 3, 4} - 4 > 3 so append that to s
5. S = {1, 3, 4} - 2 is the smallest element > 1 so replace 2 with 1
6. S = {1, 2, 4} - 3 is the smallest element > 2 so replace 3 with 2
7. S = {1, 2, 4, 9} - 9 > 4 so append that to S
8. S = {1, 2, 4, 5} - 9 is the smallest element > 5 replace 9 with 5
9. S = {1, 2, 4, 5, 8} - 8 > 5 so append that to S
So the length of the LIS is 5 (the size of S).

让我们采取其他一些序列,看看这将涵盖所有可能的警告,每个都有自己的问题

说我们有1,2,3,4,9,2,3,4,5,6,7,8,10

基本上它首先构建12349,然后2将替换33将替换44将替换9 1}},然后附加5,6,7,8,10 所以看起来像1,2,2,3,4,6,7,8,10

采取我们1,2,3,4,5,9,2,10的另一种情况 这将给我们1,2,2,4,5,9,10

或以我们的1,2,3,4,5,9,6,7,8,10为例 这将给我们1,2,3,4,5,7,8,10

这样可以说明发生了什么,在第一种情况下,当你在2之后点击9时发生的关键时刻, 你怎么处理这些。好的2,3,4块不会做任何事情,当你点击5替换9因为59 实际上无关紧要9结束了第一个5增加元素的块,您将9替换为5,因为5更小,所以那里 更有可能击中某些东西> 5稍后。但你只能替换最小的元素>本身。对于前在最后一种情况下, 如果您的6未替换9,而是替换17替换28替换3,则我们得到一个包含7个元素的最终数组 因此,只需做其中几个并找出模式,这种逻辑并不是最容易翻译成纸张的。