解释算法来解决“增长最长的子序列”问题

时间:2011-09-02 14:05:52

标签: algorithm dynamic-programming imperative-programming

过去两个小时我一直试图理解这个算法,但似乎无法理解。有人可以用容易理解的方式解释一下吗?

function lis_length(a)
    n := a.length
    q := new Array(n)
    for k from 0 to n:
        max := 0;
        for j from 0 to k, if a[k] > a[j]:
            if q[j] > max, then set max = q[j].
        q[k] := max + 1;
    max := 0
    for i from 0 to n:
        if q[i] > max, then set max = q[i].
    return max;

2 个答案:

答案 0 :(得分:5)

在第一个(双)循环终止后,q[i]是在位置i结束的最长增长子序列的长度。

要了解双循环的工作原理,假设q[j]已经包含在j位置结束的最大增加子序列的长度,但仅限于j之间的0k-1。鉴于此,您将如何计算q[k]

好吧,您会找到j j < ka[j] < a[k]的所有q[j],查看哪些相应的q[k]值最大,添加一个,然后存储该值在q[j]。这正是内循环的作用。

因此,在进入内循环时,0已经在k-1k之间具有正确的j值。退出时,它还具有q[i]的正确值。因此,当双循环退出时,i具有0n之间所有{{1}}的正确值。

最后一个循环只选择其中最大的那个,这就是答案。

答案 1 :(得分:2)

对于每个元素集,使用当前元素生成的元素的最长子序列的计数增加一个当前元素之前的元素的最长子序列的长度,使得它们的最大值小于当前元素的值。

该算法采用正数数组(不能有零或更少的元素)。