LIS 最長不下降子串行

2022-05-03 02:39:10 字數 1088 閱讀 5023

輸入乙個n,以及n個資料,輸出最長的不下降的子串行

大意:有兩種思路:

1.o(n^2)想法

用乙個num來記錄以該數字為末數字的長度

用乙個if限制兩個條件,後面小於前面並且後面的長度大於前面的長度+1那麼說明需要更新了,最後只要遍歷所有的數字在num中看以那個數字為開始點的長度最長。這個比較好理解

#includeconst

int max = 150

;int

a[max],num[max];

intmain()

}int max = 0

;

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

printf("%d

",max);

return0;

}

view code

2.o(n*logn)想法

這個比較難以理解

用b[k]來記錄以該下標為長度,且最後乙個數為它的數值

b[1] = a[1],然後迴圈,判斷是否a[i] > b[k],如果是的話,b長度就變長,值就變成a[i],否則的話從長度為1開始找一直找到以長度為k的,因為b是單調遞增的,所以在其中找大於b[j],小於b[j+1]這個值的下標,就相當於在乙個單調的串中找乙個與要找的n相同的值,用二分法,不過以下標為二分的話,l = mid + 1,r = mid -1 ,返回l的值,左閉右開。

#includeusing

namespace

std;

const

int max = 1010

;int

a[max],b[max];

intmain()

b[l] =a[i];}}

printf(

"%d\n

",k);

return0;

}

view code

也可以呼叫庫函式 lower_bound  二分函式

lower_bound(a, a + n, k) 用二分找a[i]大於k的最小的指標

int dp[maxn];

void solve()

最長不下降子串行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...