最長上公升子串行nlogn演算法

2022-02-27 23:42:54 字數 637 閱讀 3008

lis問題是經典的動態規劃問題,它的狀態轉移相信大家都很熟悉:

f[i] = f[k] + 1  (k < i 且 a[k] < a[i])

顯然這樣做複雜度是o(n^2)

有沒有更快的演算法呢?

當然,你會發現你在往前找的過程中實際上就是在查詢最大值的過程,如果能應用二分就很有機會降到nlogn

但是原f序列並不滿足二分性質吶。。怎麼辦呢?

我們要的是往前長度最大的,我們的二分目標就是長度

不妨開乙個長度陣列len[i],表示長度為i的上公升子串行最後末尾的值的最小值

對於沒算出的len,設為inf,每次算完f[i]後,就對len[f[i]]進行更新

這樣子我們就可以每次logn算出f[i]

為什麼這樣是正確的呢?

應為len陣列是單調遞增的,長度為2的末尾值一定比長度為3的要小,所以我們寫的二分一定是最大值的二分

fill(len,len + maxn,inf);

len[0] = 0;

int ans = 0;

rep(i,n)

f[i] = l + 1;

len[f[i]] = min(len[f[i]],a[i]);

ans = max(ans,f[i]);

} cout<

最長上公升子串行nlogn演算法

這題目是經典的dp題目,也可叫作lis longest increasing subsequence 最長上公升子串行 或者 最長不下降子串行。很基礎的題目,有兩種演算法,複雜度分別為o n logn 和o n 2 a.o n 2 演算法分析如下 a 1 a n 存的都是輸入的數 1 對於a n 來...

最長上公升子串行nlogn演算法

定義d k 長度為k的上公升子串行的最末元素,若有多個長度為k的上公升子串行,則記錄最小的那個最末元素。注意d中元素是單調遞增的,下面要用到這個性質。首先len 1,d 1 a 1 然後對a i 若a i d len 那麼len d len a i 否則,我們要從d 1 到d len 1 中找到乙個...

最長上公升子串行nlogn演算法

這題目是經典的dp題目,也可叫作lis longest increasing subsequence 最長上公升子串行 或者 最長不下降子串行。很基礎的題目,有兩種演算法,複雜度分別為o n logn 和o n 2 a.o n 2 演算法分析如下 a 1 a n 存的都是輸入的數 1 對於a n 來...