最長上公升子串行(longest increasing subsequence),簡稱 lis,即在乙個給定的數值串行中,找到乙個子串行,使得這個子串行元素的數值依次遞增,並且這個子串行的長度盡可能地大。最長遞增子串行中的元素在原序列中不一定是連續的,比如
最長上公升子串行為
0, 4, 10 - 長度為 3
最長上公升子串行為
2,4,32,35 - 長度為 4
最長上公升子串行為
4 - 長度為 1
演算法實現
假設長度為 n 的陣列 arr,這裡的 i 代表 arr[i] 即為子串行結尾元素
l(i) = 1 + max(l(j)) 需要滿足 0 < j < i 且 arr[j] < arr[i]
l(i) = 1 如果 j 不存在
比如
求 arr = 的最長上公升子串行長度
即求解 max( l(1),l(2),l(3),l(4),l(5) )
l(1) = 1
l(2) = 1 (因為50 > 33 即 j 不存在)
l(3) = 1 + max( l(2) ) = 2 因為 50 > 34
l(4) = 1 + max( l(3), l(2) ) 因為 50 > 40
由上可值 l(3) = 2, l(2) = 1 即 max( l(3), l(2) ) == 2
即l(4) = 1+2 = 3
l(5) = 1
可得 max( l(1),l(2),l(3),l(4),l(5) ) = l(4) = 3
即arr最長上公升子串行長度為3
#include int lis(int *arr, int n)
return max;
} int main()
; int n = sizeof(arr) / sizeof(int);
printf("length of lis is %d\n", lis(arr, n));
return 0;
}
上面解法包含重疊子問題,下面是乙個求長度為4的陣列的lis長度,可以看出出現了很多重複
lis(4)
/ | \
lis(3) lis(2) lis(1)
/ \ |
lis(2) lis(1) lis(1)
/lis(1)
下面是利用**法(tabular method)實現,可以去除重疊子問題請參考 最長上公升子串行
問題描述 乙個數的序列bi,當b1 b2 bs的時候,我們稱這個序列是上公升的。對於給定的乙個序列 a1,a2,an 我們可以得到一些上公升的子串行 ai1,ai2,aik 這裡1 i1 i2 ik n。比如,對於序列 1,7,3,5,9,4,8 有它的一些上公升子串行,如 1,7 3,4,8 等等...
最長上公升子串行
最長上公升子串行問題是各類資訊學競賽中的常見題型,也常常用來做介紹動態規劃演算法的引例,筆者接下來將會對poj上出現過的這類題目做乙個總結,並介紹解決lis問題的兩個常用 演算法 n 2 和 nlogn 問題描述 給出乙個序列a1,a2,a3,a4,a5,a6,a7.an,求它的乙個子串行 設為s1...
最長上公升子串行
最長上公升子串行問題 給出乙個由n個數組成的序列x 1.n 找出它的最長單調上公升子串行。即求最大的m和a1,a2 am,使得a1動態規劃求解思路分析 o n 2 經典的o n 2 的動態規劃演算法,設a i 表示序列中的第i個數,f i 表示從1到i這一段中以i結尾的最長上公升子串行的長度,初始時...