動態規劃之最長公共子串行問題
前言:
乙個給定序列的子串行,就是將給定的序列中零個或多個元素去掉後得到的結果。其形式化定義如下:給定乙個序列x=,另乙個序列z=滿足如下條件時稱為x的子串行,即存在乙個嚴格遞增的x下表序列(i1,i2…….ik),對所有j=1,2,3,…..k滿足xi=zj例如z=是x=的子串行對應的下標的序列為<2,3,5,7>
給定兩個序列x,y,如果z即使x的序列又是y的子串行我們稱x和y的公共子串行
問題描述:
給定兩個序列x和y=求x和y長度最長的公共最長子序列 簡稱lcs問題
問題的解決:
步驟一:刻畫最長公共子串行的特徵:
字首的嚴格定義:
給定乙個序列x=對i=0,1,2…..m,定義x的第i字首為xi=例如:x則x4=,x0為空串
lcs的最優子結構:
x=1,x2,…,xm> 和 y=1,y2,…,yn>為兩個序列的,z=為x和y的任意lcs
如果xm= yn,那麼zk=xm= yn而且zk-1是xm-1和 yn-1的乙個lcs
如果xm≠ yn,那麼zk≠xm蘊含z是xm-1和 y的乙個lcs
如果xm≠ yn,那麼zk≠yn蘊含z是x和 yn-1的乙個lcs
v 步驟2:乙個遞迴解
c[i,j]為序列xi 和yj
乙個lcs的長度
v步驟3:乙個遞迴解計算lcs長度
步驟4構造lcs
我們可以利用lcs_length返回的表b快速構造x
和y=只需簡單的從b[m][n]開始並按箭頭方向進行追蹤下去即可。當在表b[i][j]中遇到乙個左上箭頭意味著xi=yj是lcs的乙個元素
偽**:
print_lcs(b,x,i,j)
1 if i==0orj==0
2 return
3if b[i,j]==」左上箭頭」
4 print_lcs(b,x,i-1,j-1)
5 print xi
6 elseif n[i,j]==」上箭頭」
7 print_lcs(b,x,i-1,j-1)
8else print_lcs(b,x,i,j-1)
--------------------------------c++對以上演算法的實------------------------------------
#define maxnumber 20
char b[maxnumber][maxnumber];
static int mem[20];
int num=0;
void lcs_length(char x,char y,int xlength,int ylength)
else if(c[i-1][j]>=c[i][j-1])
else}}
}int print_lcs(char b[maxnumber][maxnumber],char x,int xlength,int ylength)
else if(b[xlength][ylength]=='@')
else print_lcs(b,x,xlength,ylength-1);
}void main()
;char y=;
xlength=sizeof(x)/sizeof(char);
ylength=sizeof(y)/sizeof(char);
lcs_length(x,y,xlength-1,ylength-1);
print_lcs(b,x,xlength-1,ylength-1);
cout
cout
cout
for(int i=0;icout<
動態規劃之最長公共子串行(lcs)
最長公共子串行的定義是,乙個數列z分別是已知數列的子串行 子串行不一定是連續序列,是在該序列中刪去若干元素後得到的序列 且是所有符合此條件序列中最長的,則z成為最長公共子串行lcs longest common subsequences 有些地方則說公共子串就是要求連續的子串行,有些地方則不是,這裡...
動態規劃之 最長公共子串行 LCS
這個問題是動態規劃演算法中的乙個經典問題,先看問題描述 lcs 兩個字串 x和 y,找到他們最長的公共子串行,該序列不要求是連續的。公共子串行的意思就是序列的相對順序是不變的,但是序列不一定是連續的。例如 x bdcaba y abcbdab 他們的最長公共子串行是bcba和bdab,長度都為4,找...
動態規劃之最長公共子串行(LCS)
動態規劃法 dynamic programming 通常用於求解最優化問題 optimization problem 它適用於最優子結構和重疊子問題。這顯然與分治法是不同的,分治法將問題劃分為不重疊的子問題,然後分別求解這些子問題,最後將這些問題合併得到最終的解。對於具有公共子問題的情況,分治法會做...