最長上公升子串行 詳解

2021-07-15 05:15:33 字數 2399 閱讀 4559

最長上公升子串行

時間限制: 10 sec   記憶體限制:128 mb

題目描述

給定乙個序列,初始為空。現在我們將1到n的數字插入到序列中,每次將乙個數字插入到乙個特定的位置。我們想知道此時最長上公升子串行長度是多少?輸入

第一行乙個整數n,表示我們要將1到n插入序列中,接下是n個數字,第k個數字xk,表示我們將k插入到位置xk(0<=xk<=k-1,1<=k<=n)輸出

1行,表示最長上公升子串行的長度是多少。

樣例輸入 3

0 0 2

樣例輸出 2

提示 100%的資料 n<=100000

o(nlogn)演算法**:

1 #include 2

using

namespace

std;

3int i,j,n,s,t,a[100001];4

intmain()5/*

用t替換

*/22 a[l]=t;23}

24 }/*

最長序列數就是棧的大小

*/25 cout

26 }

**分析:

第乙個念頭就是用動態規劃,很顯然,這道題的轉移方程非常非常簡單,一目了然,先準備乙個陣列b

b[i]=1;

,從a[1]開始搜到i的最長上公升子串行。

這句賦值語句固然很好理解,每乙個元素,也可以視為乙個符合題意的子串行。

b[2]呢?

如圖,它顯然比a[1]高,在執行如下語句時

for(j=1;ja[j])

j小於i,也就是2,目前符合條件的只有a[1],a[1]又通過了判斷語句,它確實小於a[i],執行下一條語句:

b[i]=max(b[i],b[j]+1);

很顯然:b[2]顯然原來是1,當它和b[1]+1比時,1當然比2小,所以,b[2]自然就是2了。

再來看看時間複雜度:

很明顯,時間複雜度為o(n^2)。

那,這個方法夠快嗎?還可以,但仍然有些不盡人意。

**如下o(n^2):

#include

using namespace std;

int i,j,n,a[100],b[100],max;    

int main()    

for(max=i=0;imax) max=b[i];  

cout那麼,還有沒有更快的方法呢?

當然有,有沒有想到過,為什麼要記錄資料呢?

我們可以模擬乙個stack

在有大量資料的情況下,這演算法效率極高

但是,怎麼來優化程式呢?

我們可以這樣來模擬:

每輸入乙個數,如果這個數大於棧頂的那個數,於是把它推入棧中。

但是,如果這個數大於棧頂呢,這不證明它不可以更新棧中的

某個元素,這時,就可以運用二分查詢了。

有人可能會問:這個序列是無序的啊。沒錯,但查詢的是stack裡面的元素,而這個棧裡的所有元素,都是嚴格遞增的,所以,用二分查詢可以把問題縮減為o(nlogn)。

有些不符合邏輯,不是嗎?15的下標比17、18、20都大,為什麼能插入呢?但是如果仔細想一想,這好像並不影響正常答案,但如果要輸出最長上公升子串行,那就要改一改這個演算法了。

整個二分查詢**如下:

else

a[l]=t; }

由此,這個查詢演算法才得以下降到logn,於是,整體也就是o(nlogn)。

具體操作如下:

每次取棧頂元素和讀到的元素做比較,如果大於,則將它入棧;如果小於,則二分查詢棧中的比它大的第1個數,並替換它。最長序列長度即為最後模擬的大小。

這也是很好理解的,對於i和j,如果i

**(同上):

#include

using namespace std; 

int i,j,n,s,t,a[100001];

int main()

a[l]=t;//

如果小於,則二分查詢棧中的比它大的第1個數,並替換它,,,,那17怎麼辦???不理解,為什麼15可以插隊????}}

cout<

最長上公升子串行 LIS 詳解

最長上公升子串行 longest increasing subsequence,lis 在電腦科學上是指乙個序列中最長的單調遞增的子串行。最長上公升子串行是序列,其狀態是一維的,所以我們可以定義狀態 f i 表示以a i 結尾的最長上公升子串行 如果每乙個元素都只考慮它本身,則以a i 結尾的最長上...

最長上公升子串行

問題描述 乙個數的序列bi,當b1 b2 bs的時候,我們稱這個序列是上公升的。對於給定的乙個序列 a1,a2,an 我們可以得到一些上公升的子串行 ai1,ai2,aik 這裡1 i1 i2 ik n。比如,對於序列 1,7,3,5,9,4,8 有它的一些上公升子串行,如 1,7 3,4,8 等等...

最長上公升子串行

最長上公升子串行問題是各類資訊學競賽中的常見題型,也常常用來做介紹動態規劃演算法的引例,筆者接下來將會對poj上出現過的這類題目做乙個總結,並介紹解決lis問題的兩個常用 演算法 n 2 和 nlogn 問題描述 給出乙個序列a1,a2,a3,a4,a5,a6,a7.an,求它的乙個子串行 設為s1...