找到最长递增子序列 (LIS)
给定 A= {1,4,2,9,7,5,8,2},找到 LIS。显示填充的动态规划表以及如何找到解决方案。
我的书没有涉及 LIS,所以我有点不知道如何开始。对于 DP 表,我对最长公共子序列做了类似的事情。任何有关如何开始此操作的帮助将不胜感激。
Given A= {1,4,2,9,7,5,8,2}, find the LIS. Show the filled dynamic programming table and how the solution is found.
My book doesnt cover LIS so im a bit lost on how to start. For the DP table, ive done something similar with Longest Common Subsequences. Any help on how to start this would be much appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
关于这个主题已经有很多答案,但这是我的演练,我将此网站视为未来后代答案的存储库,这只是为了在我自己完成它时提供额外的见解。
最长递增子序列(LIS)问题是找到给定序列的最长子序列的长度,使得该序列的所有元素
子序列按升序排序。例如,
让
S[pos]
的LIS长度被定义为结束长度pos的递增序列的最小整数。现在迭代输入集中的每个整数 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
步骤:
让我们采取一些其他序列来查看这将涵盖所有可能的警告,每个序列都会提出自己的问题,
比如我们有
1,2,3,4,9,2,3,4,5,6,7,8,10
基本上它首先构建
12349
,然后构建2
将替换3
,3
将替换4
,4
将替换9< /code>,然后追加
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
,这样就可以说明发生了什么,在第一种情况下,关键时刻是当您点击 < 时会发生什么
9
之后的 code>2,你如何处理这些。好吧,
2,3,4
块实际上不会做任何事情,当您点击5
时,您会替换9
因为5
和9
实际上是不可微分的
9
结束了第一个5
递增元素的块,您将9
替换为5
因为5
较小,所以有击中某物的潜力更大>
5
稍后。但你只替换最小的元素>本身。对于前。在最后一种情况下,如果您的
6
没有替换9
而是替换1
并且7
替换2
> 和8
替换3
,然后我们得到一个由 7 个元素组成的最终数组9. 所以只要做几个这样的事情并找出模式,这个逻辑并不是最容易转化为纸质的。
Already plenty of answers on this topic but here's my walkthrough, I view this site as a repository of answers for future posterity and this is just to provide additional insight when I worked through it myself.
The longest Increasing Subsequence (LIS) problem is to find the length of the longest subsequence of a given sequence such that all elements of the
subsequence are sorted in increasing order. For example, length of LIS for
Let
S[pos]
be defined as the smallest integer that ends an increasing sequence of length pos.Now iterate through every integer X of the input set and do the following:
If X > last element in S, then append X to the end of S. This essentialy means we have found a new largest LIS.
Otherwise find the smallest element in S, which is >= than X, and change it to X. Because S is sorted at any time, the element can be found
using binary search in log(N).
Total runtime - N integers and a binary search for each of them - N * log(N) = O(N log N)
Now let's do a real example:
Set of integers: 2 6 3 4 1 2 9 5 8
Steps:
Let's take some other sequences to see that this will cover all possible caveats, each presents its own issue
say we have
1,2,3,4,9,2,3,4,5,6,7,8,10
basically it builds out
12349
first, then2
will replace3
,3
will replace4
,4
will replace9
, then append5,6,7,8,10
so will look like
1,2,2,3,4,6,7,8,10
take the other case we have
1,2,3,4,5,9,2,10
this will give us
1,2,2,4,5,9,10
or take the case we have
1,2,3,4,5,9,6,7,8,10
this will give us
1,2,3,4,5,7,8,10
so that kind of illuminates what goes on, in the first case the critical juncture being what happens when you hit the
2
after the9
,how do you deal with these. well the block of
2,3,4
won't do anything really, when you hit5
you replace the9
because the5
and9
are virtually indifferentiable
9
ends the block of the first5
increasing elements, you replace9
with5
because5
is smaller so thereis greater potential to hit something >
5
later on. but you only replace the smallest element > itself. for ex. in the last case,if your
6
doesn't replace9
but instead replaces1
and7
replaces2
and8
replaces3
, then we get a final array of 7 elements insteadof 9. So just do a couple of these and figure out the pattern, this logic isn't the easiest to translate to paper.
LIS 和 LCS 之间有非常密切的关系。
http://en.wikipedia.org/wiki/Longest_increasing_subsequence
我认为这篇文章解释得很好。基本上,这个想法是,您可以将一个问题简化为另一个问题(在涉及动态编程的许多情况下都是这种情况)。
There's a very strong relation between LIS and LCS.
http://en.wikipedia.org/wiki/Longest_increasing_subsequence
This article explains it pretty well I think. Basically the idea is, you can reduce one problem to the other (this is the case in many situations involving Dynamic programming).