問題描述:
給兩個字串行a和b,求長度最長的公共字序列,並將最長公共字序列輸出來。例子如下:a序列abcbdab,b序列bdcaba則最長公共子串行是bdab。
分析:
之前就有了解這個方面的內容,也知道大概思路。就是判斷兩個序列的最後一位是否相同,若相同則繼續判斷i-1和j-1是否相同;若不相同則比較i和j-1兩者誰更大,繼續比較更大的哪乙個,下面就是**:
d(i,j)為a1,a2,a3,...,ai和b1,b2,b3,...,bj的lcs長度,
當a[i]==b[j]時,d(i,j)=d(i-1,j-1)+1;
否則d(i,j)=max(d(i-1,j),d(i,j-1));
但是,就是知道這樣的思路,我還是寫不出來**,就是寫出來了也是答案不對的。上面的式子要求必須先知道d(i-1,j-1)或者d(i-1,j)或者d(i,j-1)的值才可以解決掉。因此不能逆序來實現這個。因此寫不下去的**,後來在網上扒**,發現他們都是順序實現的,當時百思不得其解,後來有人提到到了數字三角形,於是乎,就覺得對啊,求數字三角形時也行要得到最後來獲取結果,而它就是從底部向頂部上計算而去的,只不過就是在最後一行的時候就構造了一組資料為零的。於是就很自然的就得到了最後的結果。這個方法在這裡一樣適用,其實應該很好就應該想到,因為你無法計算d(i-1,j-1)的值就不能寫**,必須解決的問題,自然而然就想到了由底向上的方法。
但是在扒**的過程中我發現了一張圖表,當時也覺得看不懂是怎麼填的數,後來就看懂了啊,就是根據狀態轉移方程試來寫的,就很簡單可以寫出來。列印路徑的話,只需要新增乙個變數,這個變數可以知道dp(i,j)是根據dp(i-1,j-1)dp(i-1,j)d(i,j-1)哪乙個量得到的,最後遞迴輸出它的最長公共子串行。
**:
#include
#include
#include
#include
#include
using
namespace
std;
const
int maxx=1000+10;
string s1,s2;
int c[maxx][maxx],d[maxx][maxx];
void printlcs(int i,int j)
else
if(d[i][j]==2)
else
if(d[i][j]==3)
}int main()
else
if(c[i-1][j]>c[i][j-1])
else
}cout
0;}
LCS 最長公共子串行
問題描述 我們稱序列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最長公共子串行
求兩個字串的最大公共子串行問題 子串行的定義 若給定序列x 則另一串行z 是x的子串行是指存在乙個嚴格遞增下標序列使得對於所有j 1,2,k有 zj xij。例如,序列z 是序列x 的子序列,相應的遞增下標序列為。分析 用動態規劃做 1.最長公共子串行的結構 事實上,最長公共子串行問題具有最優子結構...
LCS最長公共子串行
lcs是longest common subsequence的縮寫,即最長公共子串行。乙個序列,如果是兩個或多個已知序列的子串行,且是所有子串行中最長的,則為最長公共子串行。複雜度對於一般的lcs問題,都屬於np問題。當數列的量為一定的時,都可以採用動態規劃去解決。解法動態規劃的乙個計算最長公共子串...