最長公共子串行+sdutoj2080改編:
傳送門:
設序列x=和y=的最長公共子串行為z=,
記: xk為序列x中前k個連續字元組成的子串行,
yk為序列y中前k個連續字元組成的子串行,
zk為序列z中前k個連續字元組成的子串行,
顯然有下式成立:
(1)若xm=yn,則zk=xm=yn,且zk-1是xm-1和yn-1的最長公共子串行;
(2)若xm≠yn且zk≠xm,則z是xm-1和y的最長公共子串行;
(3)若xm≠yn且zk≠yn,則z是x和yn-1的最長公共子串行。
可見,兩個序列的最長公共子串行包含了這兩個序列的字首序列的最長公共子串行。
要找出序列x=和y=的最長公共子串行,可按下述遞推方式計算:
當xm=yn時,找出xm-1和yn-1的最長公共子序 列,然後在其尾部加上xm即可得到x和y的最長公共子串行;
當xm≠yn時,必須求解兩個子問題:找出xm-1和y的最長公共子串行以及xm和yn-1 的最長公共子串行,這兩個公共子串行中的較長
者即為x和y的最長公共子串行
設l[i][j]表示子串行xi和yj的最長公共子串行的長度,可得如下動態規劃函式:
l[0][0] = l[i][0] = l[0][j] = 0 (1≤i≤m,1≤j≤n)
l[i][j]只是記錄子串行的長度,要列印得到xm
和yn具體的最長公共子串行,設二維表s[m+1][n+1],其中s[i][j]表示在計算l[i][j]的過程中的搜尋狀態,並且有:
若s[i][j]=1,表明ai=bj,則下乙個搜尋方向是s[i-1][j-1];
若s[i][j]=2,表明ai≠bj且l[i][j-1]≥l[i-1][j],則下乙個搜尋方向是s[i][j-1];
若s[i][j]=3,表明ai≠bj且l[i][j-1]<l[i-1][j],則下乙個搜尋方向是s[i-1][j]。
舉例:序列x=(a,b,c,b,d,b),y=(a,c,b,b,a,b, d, b,b),建立兩個(m+1)×(n+1)的二維表l和表s,分別存放搜尋過程中得到的子串行的長
度和狀態。
下面**為sdutoj2080改編**:
1演算法分析:在演算法中,/**/
2 # include 3
using
namespace
std;45
int commonorder( int len1, int len2, char x, char y, char
z);6
int l[501][501];7
int s[501][501];8
intmain()922
}23return0;
24}2526
int commonorder(int m, int n, char x, char y, char
z)27
33for( i=0; i<=m; i++)
3437
for( i=1; i<=m; i++)
3846
else
if( l[i][j-1]>=l[i-1
][j] )
4751
else
5256}57
}58 i =m;
59 j =n;
60 k =l[m][n];
61while( i>=0 && j>=0)62
70else
if( s[i][j]==2)71
74else
7578}79
return
l[m][n];
80 }
第乙個for迴圈的時間效能是o(n);
第二個for迴圈的時間效能是o(m);
第三個迴圈是兩層巢狀的for迴圈,其時間效能是o(m×n);
第四個for迴圈的時間效能是o(k),而k≤min,所以,演算法的時間複雜性是o(m×n)。
最長公共子串行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 表示...