O nlogn LIS及LCS演算法

2021-07-05 23:05:30 字數 1258 閱讀 7624

morestep學長出題,考驗我們,第二題裸題但是資料範圍令人無奈,考試失利之後,刻意去學習了下優化的演算法

一、o(nlogn)的lis(最長上公升子串行)

設當前已經求出的最長上公升子串行長度為len。先判斷a[t]與d[len]。若a [t] > d[len],則將a[t]接在d[len]後將得到乙個更長的上公升子串行,len = len + 1, d[len] = a [t];否則,在d[1]..d[len]中,找到最大的j,滿足d[j] < a[t]。令k = j + 1,則有a [t] <= d[k],將a[t]接在d[j]後將得到乙個更長的上公升子串行,更新d[k] = a[t]。

不過這種方法要注意,d中並不是我們所求的最長上公升子串行

**如下:

#include#include#include#includeusing namespace std;

int search(int *a,int len,int n)

printf("%d",len);

return 0;

}

二、o(nlogn)的lcs

其實就是把兩個序列化成乙個序列,然後做一遍上述o(nlogn)的lis即可

轉換方法如下:

有樣例7 8

1 7 5 4 8 3 9

1 4 3 5 6 2 8 9

陣列a中 1  2  3  4  5  6  7

分別對應1  7  5  4  8  3  9 不妨在陣列b中的相同的數用在陣列a中的 下標來表示(沒有出現的用0)

由上述描述則陣列b原來為: 1  4  3  5  6  2  8  9

可以表示為:                      1  4   6  3  0  0  5  7

然後對處理後的陣列進行一遍lis,lis中的len即為所求

注意:這種o(nlogn)的lcs只適用於兩兩互不相同的兩個序列之中,不然會退化(但可以維護二叉搜尋樹,然而我並不會/(ㄒoㄒ)/~~),但這種lis是可重的

下面是**:

#include#include#include#includeusing namespace std;

int a[100000]=,c[100000]=,d[100000]=;

int search(int *a,int len,int n)

printf("%d",len);

return 0;

}

此處感謝morestep學長的傾情講解

O nlogn LIS及LCS演算法

morestep學長出題,考驗我們,第二題裸題但是資料範圍令人無奈,考試失利之後,刻意去學習了下優化的演算法 一 o nlogn 的lis 最長上公升子串行 設當前已經求出的最長上公升子串行長度為len。先判斷a t 與d len 若a t d len 則將a t 接在d len 後將得到乙個更長的...

演算法 LCS及輸出LCS

最長公共子串行 include using namespace std typedef long long ll char a 1005 b 1005 pos i j 的三個值1,2,3分別表示左 左上和上 pos記錄當前lcs是從哪個點過來的,如果不等於2說明當前值是繼承自上乙個相等的點 所以如果...

LCS 演算法的改進

通常兩個字串的最大公共子串的問題是通過下面的演算法來完成的 把字串1 長度m 橫排,串2 長度n 豎排,得到乙個m n的矩陣c,矩陣的每個元素的值如下,如果m i n j 則c j i 1,否則,c j i 0。然後找出矩陣中連續是1的對角線最長的乙個,則對角線的長度就是公共子串的長度.一看這個方法...