樸素做法的思路:
1.用f[i][j]表示a中前i個,b中前j個並且以b[j]結尾的解
2.狀態轉移:分類
1.不包含a[i]的情況,那麼f[i][j]=f[i-1][j],也就是和a的前i-1個,b的前j個並且以b[j]結尾的情況一樣。
2.包含a[i],這就意味者a[i]==b[j],那麼這就要列舉f[i-1][k],1<=k#include
#include
#include
using
namespace std;
const
int n=
3010
;int f[n]
[n];
int a[n]
;int b[n]
;int
main()
f[i]
[j]=
max(maxv,f[i]
[j]);}
}}int res=0;
for(
int i=
1;i<=n;i++
)res=
max(res,f[n]
[i])
; cout << res;
}然後我們發現每次迴圈求得的maxv是滿足a[i] > b[k]的f[i - 1][k] + 1的字首最大值。
因此可以直接將maxv提到第一層迴圈外面,減少重複計算,此時只剩下兩重迴圈。
最終答案枚舉子序列結尾取最大值即可
#include
#include
#include
using
namespace std;
const
int n =
3010
;int n;
int a[n]
, b[n]
;int f[n]
[n];
intmain()
}int res =0;
for(
int i =
1; i <= n; i ++
) res =
max(res, f[n]
[i])
;printf
("%d\n"
, res)
;return0;
}
最長公共上公升子串行
題目描述 給定兩個整數序列,求它們的最長上公升公共子串行。輸入描述 輸入兩組資料,每組資料代表乙個整數序列,其輸入格式為 第一行輸入長度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 那...
最長公共(上公升)子串行
題目 common subsequence 題目描述 給定兩個字串a和b 或數字序列 求乙個字串,使得這個字串是所給兩個字串的最長公共部分 可以不連續 動態規劃的做法 時間複雜度,o n m include include include include using namespace std co...