最長公共(上公升)子串行

2021-09-25 03:18:00 字數 1770 閱讀 6414

題目:common subsequence

題目描述:給定兩個字串a和b(或數字序列),求乙個字串,使得這個字串是所給兩個字串的最長公共部分(可以不連續)

動態規劃的做法:時間複雜度,o(n*m)

**:

#include

#include

#include

#include

using namespace std;

const

int manx=

2e3+10;

const

int inf=

1e9;

int dp[manx]

[manx]

;int

main()

printf

("%d\n"

,dp[i-1]

[j-1])

;}}

例題:greatest common increasing subsequence

題目描述:在最長公共子串行的基礎上,增加乙個上公升子串行的條件

假設和最長公共子串行一樣,我們規定dp[i][j]表示a的i號位和b的j號位前的lcis。在最長公共子串行中,當a[i]=b[j]時,我們直接用dp[i-1][j-1]+1來更新dp[i][j]。但在這裡,因為有上公升的限制,就不能直接通過dp[i-1][j-1]+1來得到dp[i][j]了,因為a的i-1號位和b的j-1號位前的lcis中的最後一位數不一定<

<

<

a[i]。

所以為了判斷能否通過前面的dp值來更新dp[i][j],我們這樣規定:設dp[i][j]表示a的i號位和b的j號位前並且以b[j]為結尾的lcis的長度。

這樣當a[i]=b[j]時,我們就可以尋找最大的dp[i-1][k]來更新dp[i][j](1≤

\leq

≤k≤\leq

≤j-1,b[k]<

<

<

b[j])

最後就剩下了怎麼確定k值的問題,很容易想到我們可以列舉1~j-1中所有符合條件(b[k]<

<

<

b[j])的dp[i-1][k]值,但這樣複雜度就到了o(n^3)。所以這裡我們換乙個思路:在第二層迴圈中,我們每次從左至右都更新了dp[i][1]到dp[i][m]所有值(m是序列b的長度),即以序列a固定的前i位去匹配序列b,所以這裡a[i]值是固定的,我們就可以維護乙個pos值,使得dp[i-1][pos]是在條件b[pos]**實現:

ans=0;

memset

(dp,0,

sizeof

(dp));

for(

int i=

1; i<=n; i++

)else dp[i]

[j]=dp[i-1]

[j];

}}

看到這裡不難發現每次更新只用到了dp[i-1]的那一層,所以dp我們可以優化成一維。

ans=0;

memset

(dp,0,

sizeof

(dp));

for(

int i=

1; i<=n; i++)}

}

變型例題:吉哥系列故事——完美隊形i

最長公共上公升子串行

題目描述 給定兩個整數序列,求它們的最長上公升公共子串行。輸入描述 輸入兩組資料,每組資料代表乙個整數序列,其輸入格式為 第一行輸入長度m 1 m 500 第二行輸入該序列的m個整數ai 231 ai 231 輸出描述 輸出共兩行。第一行輸出兩個序列的最長上公升公共子串行的長度l 第二行輸出該子串行...

最長公共上公升子串行

首先,在 a i b j 的時候有 dp i j dp i 1 j 為什麼呢?因為 dp i j 是以b j 為結尾的 lcia 如果dp i j 0 那麼就說明 a 1 a i 中必然有乙個字元 a k 等於b j 如果dp i j 等於0 呢?那賦值與否都沒有什麼影響了 因為 a k a i 那...

最長公共上公升子串行

熊大媽的奶牛在小沐沐的薰陶下開始研究資訊題目。小沐沐先讓奶牛研究了最長上公升子串行,再讓他們研究了最長公共子串行,現在又讓他們研究最長公共上公升子串行了。小沐沐說,對於兩個數列a和b,如果它們都包含一段位置不一定連續的數,且數值是嚴格遞增的,那麼稱這一段數是兩個數列的公共上公升子串行,而所有的公共上...