動態規劃-最長公共子串行 (lcs)
題目描述:
給定兩個字串(或數字序列)a和b,求乙個字串,使得這個字串是a和b的最長公共部分(子串行可以不連續)。
如樣例所示,字串"sadstory"與"adminsorry"的最長公共子串行為"adsory",長度為6
動態規劃的解法
令dp[i][j]
表示字串a的i
號位和字串b的j
號位之前的lcs長度(下標從1開始),如dp[4][5]
表示」sads「與"admin"的lcs長度。那麼可以根據a[1]和b[j]的情況,分為兩種決策:
若a[i] == b[j],則字串a與字串b的lcs增加了1位,即有dp[i][j] = dp[i-1][j-1]+1
。例如,樣例中dp[4][6]
表示"sads"與"admins"的lcs長度,比較a[4]與b[6],發現兩者都是』s』,因此dp[4][6]
就等於dp[3][5]
加1,即為3。
若a[i] != b[j],則字串a的i號位和字串b的j號位之前的lcs無法延長,因此dp[i][j]
將會繼承dp[i-1][j]
與dp[i][j-1]
中的較大值,即有dp[i][j]
= max。例如,樣例中dp[3][3]
表示"sad"與"adm"的lcs長度,我們比較a[3]與b[3],發現』d』不等於』m』,這樣dp[3][3]
無法再原先的基礎上延長,因此繼承自"sa"與"adm"的lcs,"sad"與"ad"的lcs中的較大值,即"sad"與"ad"的lcs長度-2。
狀態轉移方程。
邊界:dp[i][0] = dp[0][j] = 0 (0 <= i <= n,0 <= j <= m)
這樣狀態dp[i][j]
只與之前的狀態有關,由邊界出發就可以得到整個dp陣列,最終dp[n][m]
就是需要的答案,時間複雜度為o(nm)。
**如下:
#include
#include
#include
using namespace std;
const
int n =
100;
char a[n]
,b[n]
;int dp[n]
[n];
intmain()
for(
int j =
0; j <= lenb ; j++
)// 狀態轉移方程
for(
int i =
1; i <= lena ; i++
)else}}
// dp[lena][lenb]是答案
printf
("%d\n"
,dp[lena]
[lenb]);
return0;
}
執行結果 最長公共子串行LCS(動態規劃)
1.描述 給定兩個序列 x y 求x和y的乙個最長公共子串行。2.分析 設最長子序列 z 則 1 若 xm yn 則 zk xm yn,且z k 1 是 x m 1 和 y n 1 的最長公共子串行 2 若 xm yn 且 zk xm 則 z 是 x m 1 和 y 的最長公共子串行 3 若 xm ...
最長公共子串行(LCS) 動態規劃
首先,動態規劃的關鍵是將之前所計算的結果儲存起來,之後直接呼叫!1.問題描述 字串的子串行 是指從該字串中去掉任意多個字元後剩下的字元在不改變順序的情況下組成的新字串。最長公共子串行 是指多個字串可具有的長度最大的公共的子串行。比如 adbcbd bdcaba這兩個字串的最長公共子串行是dcb 2....
動態規劃 最長公共子串行(LCS)
最長公共子串行也是動態規劃中的乙個經典問題。有兩個字串 s1 和 s2,求乙個最長公共子串,即求字串 s3,它同時為 s1 和 s2 的子串,且要求它的長度最長,並確定這個長度。這個問題被我們稱為最長公共子串行問題。與求最長遞增子串行一樣,我們首先將原問題分割成一些子問題,我們用 dp i j 表示...