題目描述 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...