CODEVS 1408 最長公共子串行

2021-08-24 23:21:47 字數 1384 閱讀 9204

題目描述 description

熊大媽的奶牛在小沐沐的薰陶下開始研究資訊題目。小沐沐先讓奶牛研究了最長上公升子串行,再讓他們研究了最長公共子串行,現在又讓他們要研究最長公共上公升子串行了。

小沐沐說,對於兩個串a,b,如果它們都包含一段位置不一定連續的數字,且數字是嚴格遞增的,那麼稱這一段數字是兩個串的公共上公升子串,而所有的公共上公升子串中最長的就是最長公共上公升子串了。

奶牛半懂不懂,小沐沐要你來告訴奶牛什麼是最長公共上公升子串。不過,只要告訴奶牛它的長度就可以了。

輸入描述 input description

第一行n,表示a,b的長度。

第二行,串a。

第三行,串b。

輸出描述 output description

輸出長度

樣例輸入 sample input

4 2 2 1 3

2 1 2 3

樣例輸出 sample output

2資料範圍及提示 data size & hint

1<=n<=3000,a,b中的數字不超過maxlongint

. .

. . .分析

f[i][j]維護的是a中前i個,b中以第j個結尾的最長公共上公升子串行的長度

看清楚哈,i在a中的概念是前i個,意思是並不要求一定要是i結尾

b中的j是必須是j結尾的

然後怎麼轉移呢?

首先,當a[i]!=b[j]的時候,因為b[j]必須要用來結尾,所以f[i][j]=f[i-1][j]

當a[i]==b[j]的時候,會有f[i][j]=max(f[i-1][k])+1

其中b[k] < a[i] 且 k < j

因為b[k] < a[i],所以f[i][j]肯定是可以從f[i-1][k]轉移過來的

其次,因為a[i]要和b[j]組成一起,所以是從f[i-1]裡面找,而不是在f[i]裡面找,再其次,b[j]是後來要被使用的,所以k < j也是肯定的

現在問題就是,如果k是列舉,那麼複雜度就是o(n^3)了,就會tle

所以必須用o(1)的方法,求出k

再看到是b[k] < a[i],但是i是第一層迴圈,,所以我們只要在第二層迴圈裡面,維護k,使得b[k] < a[i],且f[i-1][k]是最大的

. .

. .

.程式:

#include

using

namespace

std;

int f[3001][3001],a[3001],b[3001];

int main()

}int ans=0;

for (int i=1;i<=n;i++) ans=max(f[n][i],ans);

cout

<}

COdevs1425最長公共子串

題目描述 description 輸入n 2 n 20 個字串,輸出最長公共子串。輸入描述 input description 輸入n再輸入n個字串 輸出描述 output description 輸出最大公共子串。樣例輸入 sample input 3abce cabk jaab 樣例輸出 sam...

CodeVS 3160 最長公共子串

看了好久的字尾自動機 對a串建立sam,用b串去匹配a串sam,如果在當前節點走不下去,就跳到當前節點的parent 類似ac自動機的失配指標 找到當前節點代表的狀態中長度最長的字尾,並看能不能繼續走下去。如果跳到了能繼續走下去的節點,就更新l為這個節點的max 1,同時在這個節點往下走一步 更新l...

最長公共子串行 最長公共子串

1 最長公共子串行 採用動態規劃的思想,用乙個陣列dp i j 記錄a字串中i 1位置到b字串中j 1位置的最長公共子串行,若a i 1 b j 1 那麼dp i j dp i 1 j 1 1,若不相同,那麼dp i j 就是dp i 1 j 和dp i j 1 中的較大者。class lcs el...