最長遞增子串行(LIS)

2021-08-28 04:13:32 字數 1355 閱讀 7877

本篇部落格主要講述什麼是最長公共子串行、求解最長公共子串行的思想,以及**。

什麼是最長公共子串行?

給定乙個長度為n的陣列,找出乙個最長的單調自增子序列(不要求是連續的)。例如:6 5 7 8 4 3 9 1,這裡的最長遞增子串行是或者。可以看出最長遞增子串行不唯一,但是長度一定是唯一的,不然也不能叫最長遞增子串行。

動態規劃的思想實現:

if(a[i] > a[j] && dp[i] < dp[j] + 1)

dp[i] = dp[j] + 1;

要求第i個遞增子串行,就得先求第i-1,求第i-1個就得求i-2.....以此類推,實現方法就是不斷遍歷,去查詢i前面的每乙個dp,然後去進行比較,如果滿足以上條件就進行跟新。

void lis()

for(int i = 1; i < n; i++)//遍歷

}}

二分的思想實現:

提到二分的思想就不得不想到stl中比較好用的lower_bound(start,end, elem)函式,lowe_bound的作用就是利用二分的思想去查詢第乙個小於等於elem的數。

二分上的思想去實現最長遞增子串行它的時間複雜度是o(n * logn),在第二種演算法中,在計算每乙個dp(i)時,都要找出最大的dp(j)(j

其實就是相當於,在b中先更新乙個,然後在跟新第i個,然後在b中查詢有第i在元素比在哪個位置的元素大,如果i個元素元素的元素比最後乙個大那麼最後乙個元素新增到最後位置,如果在中間的話,就用第i個元素取代第b中第乙個大於等於它的那個數的位置。

void lis()

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

}

例題:

狀態規劃:

#include#include#includeusing namespace std;

#define n 100000

int a[n], dp[n];

int main()

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

}int maxx = -1;

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

}cout《二分:

#include#include#includeusing namespace std;

#define n 100000

#define inf 10000000

int a[n], dp[n];

int main()

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

cout<}

return 0;

}

最長遞增子串行 LIS

對於這個問題,最直觀的dp方法是cnt i 表示以height i 結束的最長遞增子串行的元素的個數,遞迴方程是cnt i max for max i 0 i求出整個數列的最長遞增子串行的長度 if b i max max b i cout return 0 顯然,這種方法的時間複雜度仍為o n 2...

最長遞增子串行 LIS

給定乙個長度為n的陣列,找出乙個最長的單調自增子序列 不一定連續,但是順序不能亂 例如 給定乙個長度為6的陣列a,則其最長的單調遞增子串行為,長度為4.這個問題可以轉換為最長公共子串行問題。如例子中的陣列a,則我們排序該陣列得到陣列a 然後找出陣列a和a 的最長公共子串行即可。顯然這裡最長公共子串行...

最長遞增子串行(LIS)

300.longest increasing subsequence good 給定乙個長度為n的陣列,找出乙個最長的單調遞增子串行 不一定連續,當時先後順序不能亂 更正式的定義是 設l 是n個不同的實數的序列,l的遞增子串行是這樣乙個子串行lin 其中k1。比如陣列a 為,那麼最長遞增子串行為。以...