動態規劃典型題 最長公共子串行

2021-08-26 10:37:02 字數 2390 閱讀 7874

問題描述

我們稱序列

z = < z1, z2, ..., zk >是序列

x = < x1, x2, ..., xm >的子串行當且僅當存在嚴格上

公升的序列< i1, i2, ..., ik >,使得對

j = 1, 2, ... ,k, 有

xij = zj。比如

z = < a, b, f, c >是

x = < a, b,

c, f, b, c >的子串行。

現在給出兩個序列

x和y,你的任務是找到

x和y的最大公共子串行,也就是說要找

到乙個最長的序列

z,使得

z既是x的子串行也是

y的子串行。

輸入資料

輸入包括多組測試資料。每組資料報括一行,給出兩個長度不超過

200的字串,表示

兩個序列。兩個字串之間由若干個空格隔開。

輸出要求

對每組輸入資料,輸出一行,給出兩個序列的最大公共子串行的長度。

輸入樣例

abcfbc abfcab

programming contest

abcd mnp

輸出樣例42

0解題思路

如果我們用字元陣列

s1、s2存放兩個字串,用

s1[i]表示

s1中的第

i個字元,

s2[j]表

示s2中的第

j個字元(字元編號從

1開始,不存在「第

0個字元」),用

s1i表示

s1的前

i個字元所構成的子串, s2j表示

s2的前

j個字元構成的子串,

maxlen(i, j)表示

s1i和

s2j的

最長公共子串行的長度,那麼遞推關係如下:

if( i ==0 || j == 0 )

else if( s1[i] == s2[j] )

maxlen(i, j) = maxlen(i-1, j-1 ) + 1;

else

maxlen(i, j) = max( maxlen(i, j-1), maxlen(i-1, j)) 這個遞推關係需要證明一下。我們用

反證法來證明,maxlen(i, j)不可能比

maxlen(i, j-1)和

maxlen(i-1, j)都大。先假設

maxlen(i,

j)比maxlen(i-1, j)大。如果是這樣的話,那麼一定是

s1[i]起作用了,即

s1[i]是

s1i和

s2j的

最長公共子串行裡的最後乙個字元。同樣,如果

maxlen(i, j)比

maxlen(i, j-1)大,也能夠推

匯出,s2[j]是

s1i和

s2j的最長公共子串行裡的最後乙個字元。即,如果

maxlen(i, j)比

maxlen(i, j-1)和

maxlen(i-1, j)都大,那麼,

s1[i]應該和

s2[j]相等。但這是和應用本遞推關係

的前提----- s1[i]≠s2[j]相矛盾的。因此,

maxlen(i, j)不可能比

maxlen(i, j-1)和

maxlen(i-1, j)

都大。maxlen(i, j)當然不會比

maxlen(i, j-1)和

maxlen(i-1, j)中的任何乙個小,因此,

maxlen(i, j) = max( maxlen(i, j-1), maxlen(i-1, j)) 必然成立。

顯然本題目的「狀態」就是

s1中的位置

i和s2中的位置

j。「值」就是

maxlen(i, j)。狀

態的數目是

s1長度和

s2長度的乘積。可以用乙個二維陣列來儲存各個狀態下的「值」。本

問題的兩個子問題,和原問題形式完全一致的,只不過規模小了一點。

1. #include 2. #include 3. #define max_len 1000 4. char sz1[max_len]; 5. char sz2[max_len]; 6. int amaxlen[max_len][max_len]; 7. main() 8. 31. } 32. } 33. printf("%d\n", amaxlen[nlength1][nlength2]); 34. } 35. }

常見問題

求解最長公共子串行時,當比較到兩個字串的兩個字母不同時,應該分別將兩個字

符串向後移動乙個字元,比較這兩種情況中哪個得到的公共子串行最長。有些同學只將其中

的乙個字串向後移動,或者兩個同時移動,都是不對的。

動態規劃 最長公共子串行

問題描述 我們稱序列z z1,z2,zk 是序列x x1,x2,xm 的子串行當且僅當存在嚴格上公升的序列 i1,i2,ik 使得對j 1,2,k,有xij zj。比如z a,b,f,c 是x a,b,c,f,b,c 的子串行。現在給出兩個序列x和y,你的任務是找到x和y的最大公共子串行,也就是說要...

動態規劃 最長公共子串行

兩個序列的最長公共子序 lcs longest common length 的 每個字元可以不連續,如x y 那麼它們的最長公共子串行為。這是乙個經典的動態規劃問題,著手點還是找到 最精髓的 狀態轉移方程 假設x,y兩個序列的前i,j個位置的最大子串行已經找到為r i j 自底往上 那麼x i 與y...

動態規劃 最長公共子串行

看完演算法導論關於這部分內容之後的總結 關於最長公共子串行問題 給定兩個子串行 x y 求x和y長度最長的公共子串行。解決方法 首先先要了解lcs的最優子結構,令x y 為兩個子串行,z 為x和y的任意lcs。1 如果 xm yn 則 zk xm yn 且 zk 1 是 xm 1 和 yn 1 的乙...