求最長非降 遞增 子串行LIS的長度,及注意事項

2022-06-18 18:36:17 字數 1952 閱讀 9427

非降序列(increasing sequence)例如:

(1) 完全遞增型序列:s=

(2) 部分存在等於的序列:s=

s的非降子串行:由原序列s的元素組成的(且保持元素之間的順序不變的)組成的序列。

例如s=的子串行包括:

1個元素的:,,,,, 等6個子序列

2個元素的:,,,,,,,, 等

3個元素的:,

最長非降子串行(longest increasing sequences,lis),是s的所有非降子串行中包含元素最多的那些子串行,例如上述序列的最長子串行為和

而最長非降子串行的長度就是最長非降子串行的元素個數,例如上例中的最長非降子串行的長度為3。

求解序列s的最長非降子串行的長度通常採用動態規劃演算法:

設d(i)為前i個元素的最長非降子串行的長度,則d(i)=max, 其中 0<=j<=i,且s[j]然後寫出類似這樣的**:

public

static

void lis(int

s) }}

for(int i=0;i)

}

然後,呼叫該lis函式,求解。如

intseq=;

lis(seq);

會輸出:1 1 2 3 3 4 ,代表包含前1個元素的lis長度為1,包含前2個元素的子串行的lis長度為1,包含前3個元素的子串行的lis長度為2,。。。

需要注意的是:上述遞推公式,d(i)=max, 其中 0<=j<=i,且s[j]只適用於

以s[i]作為結尾元素的lis序列。

而如果去掉以s[i]作為結尾元素這個條件,就不能這麼求解。

例如int [ ]seq=, 用上述程式求解,會輸出1 1 2 1 3 2 (即d[3]=1 ,d[5]=2,分別代表包含前4個元素子串行的lis長度為1,包含前6個元素子串行的lis長度為2)。但其實包含前4個元素的子串行(即)的lis的長度應該是2,即,d[3]=2, lis=或, 而 d[5] 應該是3。

問題出在,上述的程式要求lis以s[i]作為結尾,即lis的最大元素為s[i],這時d[i]=max是沒錯的,但如果去掉這個限制條件,就用上面的程式求解就會出錯。

那麼,如何求解序列s的最長非降子串行的長度(不要求以s的最後乙個元素作為lis的最大元素)?

這通常需要轉化為最長公共子串行(lcs)的問題。即:序列s的lis= 將s排序後的有序序列s' 與 原序列s 的最長公共子串行。

例如,s= 的lis為或,長度為3

對s排序後的s'=, s『與 s的最長公共子串行就是和

所以,如何求解序列s的最長非降子串行的長度,首先需要進行排序,然後求lcs的長度即可。

示例**:

public

static

void

main(stringargs)

int copy=peaches.clone();

quicksort(peaches,0,n-1);

int lislength=lcs(peaches,copy)

system.out.println("lis length is"+lislength);

}public

static

void quicksort(int arr,int start,int

end)

arr[i]=arr[j];

while(iarr[i])

arr[j]=arr[i];

}arr[i]=key;

quicksort(arr,start,i-1);

quicksort(arr,i+1,end);

}public

static

int lcs(inta,int

b) }

return

c[a.length][b.length];

}

如何求lcs的長度?看這裡

LIS 求最長遞增子串行

動態規劃,dp 時間複雜度 olog n 2 include include include include include using namespace std int lis int a,int alen,int len if alen i maxlen return maxlen int m...

最長遞增子串行 LIS

對於這個問題,最直觀的dp方法是cnt i 表示以height i 結束的最長遞增子串行的元素的個數,遞迴方程是cnt i max for max i 0 i求出整個數列的最長遞增子串行的長度 if b i max max b i cout return 0 顯然,這種方法的時間複雜度仍為o n 2...

最長遞增子串行 LIS

給定乙個長度為n的陣列,找出乙個最長的單調自增子序列 不一定連續,但是順序不能亂 例如 給定乙個長度為6的陣列a,則其最長的單調遞增子串行為,長度為4.這個問題可以轉換為最長公共子串行問題。如例子中的陣列a,則我們排序該陣列得到陣列a 然後找出陣列a和a 的最長公共子串行即可。顯然這裡最長公共子串行...