最長上公升子串行

2021-10-01 15:18:58 字數 1321 閱讀 8369

最長上公升子串行(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結尾的最長上公升子串行的長度,初始時...