S
=
{
8
,
4
,
1
,
7
,
6
,
2
,
0
,
5
,
3
}
它的LIS就是(1,2,3)和(1,2,5)。除了这个定义以外,还有一种定义叫Longest Increasing Run(不知道怎么翻译),它是指找到相邻的最大个数升序排列的子序列。比如上面的序列中的(1,7)和(0,5)。
显然找到一个Longest Increasing Run是非常容易的,而找到一个LIS却不怎么简单。
为了应用Dynamic Programming,我们这里需要建立一个递归来计算最长序列的长度。这里有两种不同时间复杂度的算法:
for
i
=
1
to
total
-
1
for j = i + 1 to total
if height[j] > height[i] then
if length[i] + 1 > length[j] then
length[j] = length[i] + 1
predecessor[j] = i
for j = i + 1 to total
if height[j] > height[i] then
if length[i] + 1 > length[j] then
length[j] = length[i] + 1
predecessor[j] = i
这个算法的时间复杂度为O(n 2)。举个例子来演示这个算法,取一个序列如下:
height
=
{
9
,
5
,
2
,
8
,
7
,
3
,
1
,
6
,
4
}
length = { 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 }
predecessor = {nil , nil , nil , nil , nil , nil , nil , nil , nil}
length = { 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 }
predecessor = {nil , nil , nil , nil , nil , nil , nil , nil , nil}
然后使用这个算法,可以得到如下的结果:
height
=
{
9
,
5
,
2
,
8
,
7
,
3
,
1
,
6
,
4
}
length = { 1 , 1 , 1 , 2 , 2 , 2 , 1 , 3 , 3 }
predecessor = {nil , nil , nil , 2 , 2 , 3 , nil , 6 , 6 }
length = { 1 , 1 , 1 , 2 , 2 , 2 , 1 , 3 , 3 }
predecessor = {nil , nil , nil , 2 , 2 , 3 , nil , 6 , 6 }
另外还有一种O( n log k )的算法,其中k是实际LIS的长度。算法使用一个升序排列的序列A来存储整个LIS。A的初试状态为1个负无穷大和n-1个正无穷大组成的数组。我们要做的就是对整个序列来一次遍历,然后把每个数放到A中去看它是否是属于这个LIS,如果是就把它插入其中。这里所谓是否属于就是指从A的第一个非无穷大的数往前看,如果找到这个一个位置,即前面的数小于这个待插入的数,且后一个数大于那个数。插入的方法就是把后面的那个数替代掉即可。这种查找使用的是Binary Search,它时间复杂度为O(log k)。所以最终整个算法的时间复杂度为O(n log k)。下面给出一个例子:
0
1
2
3
4
5
6
7
8
a - 7 , 10 , 9 , 2 , 3 , 8 , 8 , 1
A -i i , i , i , i , i , i , i , i
A -i - 7 , i , i , i , i , i , i , i ( 1 )
A -i - 7 , 10 , i , i , i , i , i , i ( 2 )
A -i - 7 , 9 , i , i , i , i , i , i ( 3 )
A -i - 7 , 2 , i , i , i , i , i , i ( 4 )
A -i - 7 , 2 , 3 , i , i , i , i , i ( 5 )
A -i - 7 , 2 , 3 , 8 , i , i , i , i ( 6 )
A -i - 7 , 2 , 3 , 8 , i , i , i , i ( 7 )
A -i - 7 , 1 , 3 , 8 , i , i , i , i ( 8 )
a - 7 , 10 , 9 , 2 , 3 , 8 , 8 , 1
A -i i , i , i , i , i , i , i , i
A -i - 7 , i , i , i , i , i , i , i ( 1 )
A -i - 7 , 10 , i , i , i , i , i , i ( 2 )
A -i - 7 , 9 , i , i , i , i , i , i ( 3 )
A -i - 7 , 2 , i , i , i , i , i , i ( 4 )
A -i - 7 , 2 , 3 , i , i , i , i , i ( 5 )
A -i - 7 , 2 , 3 , 8 , i , i , i , i ( 6 )
A -i - 7 , 2 , 3 , 8 , i , i , i , i ( 7 )
A -i - 7 , 1 , 3 , 8 , i , i , i , i ( 8 )
参考资料: http://www.comp.nus.edu.sg/~stevenha/programming/prog_dynamicprogramming.html
http://www2.toki.or.id/book/AlgDesignManual/BOOK/BOOK2/NODE47.HTM