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;二、o(nlogn)的lcsint search(int *a,int len,int n)
printf("%d",len);
return 0;
}
其實就是把兩個序列化成乙個序列,然後做一遍上述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的對角線最長的乙個,則對角線的長度就是公共子串的長度.一看這個方法...