LIS 最長上公升子串行

2021-07-23 16:21:00 字數 998 閱讀 4866

最長遞增子串行問題:在一列數中尋找一些數,這些數滿足:任意兩個數a[i]和a[j],若i

設dp[i]表示以i為結尾的最長遞增子串行的長度,則狀態轉移方程為:

dp[i] = max, 1<=j

這樣簡單的複雜度為o(n^2),其實還有更好的方法。

考慮兩個數a[x]和a[y],x

按dp[t]=k來分類,只需保留dp[t]=k的所有a[t]中的最小值,設d[k]記錄這個值,d[k]=min。

這時注意到d的兩個特點(重要):

1. d[k]在計算過程中單調不公升;

2. d陣列是有序的,d[1]

利用這兩個性質,可以很方便的求解:

1. 設當前已求出的最長上公升子串行的長度為len(初始時為1),每次讀入乙個新元素x:

2. 若x>d[len],則直接加入到d的末尾,且len++;(利用性質2)

否則,在d中二分查詢,找到第乙個比x小的數d[k],並d[k+1]=x,在這裡x<=d[k+1]一定成立(性質1,2)。

/** 

最長遞增子串行o(nlogn)演算法:

狀態轉移方程:f[i] = max,1<=j=f[y],則x相對於y更有潛力。

首先根據f值分類,記錄滿足f[t]=k的最小的值a[t],記d[k]=min,f[t]=k.

1.發現d[k]在計算過程中單調不上公升

2.d[1]#include #include using namespace std;

const int n = 41000;

int a[n]; //a[i] 原始資料

int d[n]; //d[i] 長度為i的遞增子串行的最小值

int binsearch(int key, int* d, int low, int high)

return 0;

}

int lis(int* a, int n, int* d)

}

最長上公升子串行 LIS

題目 兩道題幾乎一樣,只不過對於輸入輸出的要求有所不同罷了。lis有兩種方法 一 第一種方法 時間複雜度為o n 2 狀態 dp i 區間為0 i的序列的lis 轉移方程 dp i max 1,dp k 1 0 k include include include include using name...

最長上公升子串行LIS

問題 給定n個整數a1,a2,a3,a4,a5,an,從左到右的順序盡量選出多個整數,組成乙個上公升子串行,相鄰元素不相等。例如 1,6,2,3,7,5,它的最長上公升子串行為 1,2,3,5。分析 剛開始想這個問題的時候我想用遞迴來解決問題,可是後來考慮到遞迴的時間複雜度高,就覺得不能使用,並且本...

最長上公升子串行(LIS)

問題 有乙個長為n的數列,a1,a2,an 1。請求出這個序列中最長的上公升子串行的長度。上公升子串行指的是對於任意的i j都滿足ai aj的子串行。dp i 以a i 結尾的最長上公升子串行的長度 時間複雜為o n 2 for int i 0 i1 for int j 0 jif a j max ...