最大不下降子串行(LIS)

2021-09-24 21:57:56 字數 1174 閱讀 2090

1. 問題描述:在乙個數字序列中,找到乙個最長的子串行(可以不連續),使得這個子串行是不下降的(非遞減的)

例如現有序列a = (下標從1開始)它的最長不下降子串行是長度為5,還有一些子串行是不下降子串行,比如、但是不是最長的

2. 思路分析:

① 首先我們可以列舉所有的元素,使用雙層迴圈來進行開始序列和結束序列,第一層迴圈掃瞄開始序列,第二層迴圈掃瞄結束序列,在第二層迴圈的時候掃瞄以開始序列之後的數字,並且定義指標表示當前不下降子串行所處的位置,往後進行掃瞄的過程中,假如發現後面元素的位置假如大於了指標指向的位置,那麼不下降子串行加1,而且指標往後移動一位,等到第一層迴圈結束那麼以當前開始位置序列的不下降子串行的長度就知道了,我們在一開始的時候就定義乙個全域性變數max來記錄當前最長不下降子串行的長度,等到第一層迴圈結束的時候那麼我們決定是否更新當前的最長不下降子串行的長度,由於存在著雙層迴圈那麼時間複雜度是o(n ^ 2)

② 除了使用上面的方法解決之外,我們還可以使用經典的方法來解決,可以使用動態規劃的思想來解決,定義乙個dp陣列,陣列表示的含義是以a[i]結尾的最長不下降子串行的長度,對於a[i]來說存在著兩種情況:

1)如果存在a[i]之前的元素a[j](j < i)使得a[i] >= a[j],也就是將a[i]放在a[j]結尾的lis後面的時候比以a[i]結尾的lis長度更長,那麼就將a[i]跟在以a[j]結尾的lis後面,形成一條更長的不下降子串行

2)如果a[i]之前的元素都比a[i]大,那麼a[i]治好自己形成一條lis,但是長度為1,即這個子串行裡面只有乙個a[i]

最後以a[i]結尾的lis長度就是1)2)形成的最大長度

測試資料:

8

1 2 3 -9 3 9 0 11

輸出:6

3. 下面是具體的**:

#include#include#includeusing namespace std;

const int n = 100;

int a[n], dp[n];

int main(void)

int ans = -1;

for(int i = 1; i <= n; ++i)

} ans = max(ans, dp[i]);

} printf("%d", ans);

return 0;

}

最長不下降子串行LIS

最長上公升子串行問題是解決很多問題的根本,它能幫助你理解二分的思想。考慮一下 對於乙個序列 n nn 請你查詢n nn中最長的子串行a aa,使得任意 i i j 時 a i a i a i a i a i a i 例如乙個長度為5 55的n nn 5553 331112 22444 顯然,它的最長...

LIS最長不下降子串行

在乙個序列中找到乙個最長的子串行 可以不連續 使得這個子串行不下降,即非遞減的。核心部分找到狀態轉移方程 dp i max j 1,2,i 1 a j 附上我的 include include includeusing namespace std const int maxn 10010 int d...

最長不下降子串行 (LIS)

最長不下降子串行是這樣乙個問題 在乙個數字序列中,找到乙個最長的子串行 可以不連續 使得這個子串行是不下降 非遞減 的。令dp i 表示以a i 結尾的最長不下降子串行的長度,這樣對a i 來說就會有兩種情況。1 如果存在a i 之前的元素a j jdp i 2 它前面的元素均比它大,則dp i 1...