本文**
這題目是經典的dp題目,也可叫作lis(longest increasing subsequence)最長上公升子串行 或者 最長不下降子串行。很基礎的題目,有兩種演算法,複雜度分別為o(n*logn)和o(n^2) 。
a.o(n^2)演算法分析如下:
(a[1]...a[n] 存的都是輸入的數)
1、對於a[n]來說,由於它是最後乙個數,所以當從a[n]開始查詢時,只存在長度為1的不下降子串行;
2、若從a[n-1]開始查詢,則存在下面的兩種可能性:
(1)若a[n-1] < a[n] 則存在長度為2的不下降子串行 a[n-1],a[n];
(2)若a[n-1] > a[n] 則存在長度為1的不下降子串行 a[n-1]或者a[n]。
3、一般若從a[t]開始,此時最長不下降子串行應該是按下列方法求出的:
在a[t+1],a[t+2],...a[n]中,找出乙個比a[t]大的且最長的不下降子串行,作為它的後繼。
4、為演算法上的需要,定義乙個陣列:
int d[n][3];
d[t][0]表示a[t];
d[t][1]表示從i位置到達n的最長不下降子串行的長度;
d[t][2]表示從i位置開始最長不下降子串行的下乙個位置。
實現**如下:
#include
using namespace std;
int main()
for(max=i=0;imax)
max=b[i];
cout<
b.最長不下降子串行的o(n*logn)演算法分析如下:
設 a[t]表示序列中的第t個數,f[t]表示從1到t這一段中以t結尾的最長上公升子串行的長度,初始時設f [t] = 0(t = 1, 2, ..., len(a))。則有動態規劃方程:f[t] = max (j = 1, 2, ..., t - 1, 且a[j] < a[t])。
現在,我們仔細考慮計算f[t]時的情況。假設有兩個元素a[x]和a[y],滿足
(1)x < y < t
(2)a[x] < a[y] < a[t]
(3)f[x] = f[y]
此時,選擇f[x]和選擇f[y]都可以得到同樣的f[t]值,那麼,在最長上公升子串行的這個位置中,應該選擇a[x]還是應該選擇a[y]呢?
很明顯,選擇a[x]比選擇a[y]要好。因為由於條件(2),在a[x+1] ... a[t-1]這一段中,如果存在a[z],a[x] < a[z] < a[y],則與選擇a[y]相比,將會得到更長的上公升子串行。
再根據條件(3),我們會得到乙個啟示:根據f的值進行分類。對於f的每乙個取值k,我們只需要保留滿足f[t] = k的所有a[t]中的最小值。設d[k]記錄這個值,即d[k] = min (f[t] = k)。
注意到d的兩個特點:
(1) d[k]的值是在整個計算過程中是單調不上公升的。
(2) d的值是有序的,即d[1] < d[2] < d[3] < ... < d[n]。
利 用d,我們可以得到另外一種計算最長上公升子串行長度的方法。設當前已經求出的最長上公升子串行長度為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]。最後,len即為所要求的最長上 公升子串行的長度。
在 上述演算法中,若使用樸素的順序查詢在d[1]..d[len]查詢,由於共有o(n)個元素需要計算,每次計算時的複雜度是o(n),則整個演算法的 時間複雜度為o(n^2),與原來的演算法相比沒有任何進步。但是由於d的特點(2),我們在d中查詢時,可以使用二分查詢高效地完成,則整個演算法 的時間複雜度下降為o(nlogn),有了非常顯著的提高。需要注意的是,d在演算法結束後記錄的並不是乙個符合題意的最長上公升子串行!
#include
using namespace std;
int find(int *a,int len,int n)//若返回值為x,則a[x]>=n>a[x-1]
cout<
DP 最長上公升子串行(n 2與n log n)
作為noip中的知名的問題,最長不下降子串行可謂是灰常重要 廢話不多說,正題 最長不下降有兩種方法,然而都是dp 裸dp,時間複雜度o n 2 定義 dp i 以a i 為結尾的最長上公升子串行的長度,so,dp i max 1,dp j 1 j i且a j a i 1 intn 2int a 10...
最長上公升子串行 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。分析 剛開始想這個問題的時候我想用遞迴來解決問題,可是後來考慮到遞迴的時間複雜度高,就覺得不能使用,並且本...