動態規劃 公共子串行LCS

2021-08-15 02:31:31 字數 2435 閱讀 3855

一、問題描述:

二、狀態空間:

三、狀態轉移方程:

四、實現方法:

由於f(i,j)只和f(i-1,j-1), f(i-1,j)和f(i,j-1)有關, 而在計算f(i,j)時, 只要選擇乙個合適的順序,就可以保證這三項都已經計算出來了,這樣就可以計算出f(i,j)。這樣一直推到f(n, m)就得到所要求的解了。
狀態空間的定義方法:

一般二維陣列(n*m)實現(可能會爆空間);

滾動陣列實現,只需要儲存兩行資料(2*n)。複雜度:o(n*m)

五、lcs思考

1、如果要求最長公共子串行的個數,該如何處理?

設g(i, j)為第乙個字串的前i個字元和第二個字串的前j個字元達到最長公共子串的長度(f(i, j),設為k)的字串的個數,則有:

如果f(i-1, j)=k,則g(i, j) += g(i-1, j)

如果f(i, j-1)=k,則g(i, j) += g(i, j-1)

如果a(i)=b(j),則g(i, j) += g(i-1, j-1)

如果a(i)!=b(j), 且f(i-1,j-1)=k,則g(i, j) -= g(i-1, j-1)

最終結果為:g(n, m)

2、如果要輸出乙個最長公共子串行,又該如何處理?

方法:x從1到k,掃瞄f(i, j)即可。

如果要輸出所有的最長公共子串行,又該如何處理?

方法:對f(i, j)用回溯法,從右下角開始。

如果a[i]=b[j],則a[i]為最長公共子串行的乙個元素,下一步為(i-1, j-1)

如果a[i]!=b[j],下一步為f(i-1, j)和f(i,j-1)較大的方向。如果兩者相等,則兩個方向都要考慮。

直到i或j等於0為止。

六、lcs優化

舉例說明:設有兩個字串:

x:abdba

y:dbaaba

先順序掃瞄x串,取其在y串的所有位置:

a(2,3,5) b(1,4) d(0)。

將每個字母的位置反序列,並替換x中的對應的字母,替換結果(5,3,2) (4,1) (0) (4,1) (5,3,2)

則最終每個括號裡選乙個數構成的最長嚴格遞增子串行的長度即為解。

因此最大長度為3。

七、實現**

1.二維陣列實現(hdu1159 common subsequence)

#include#include#include#include#include#includeusing namespace std;

/*程式設計人:zmh

程式設計日:2018.1.24

程式設計題:求兩個序列的最長公共子串行

程式設計思路:f(i, j)表示第乙個字串的前i個字元和第二個字串的前j個字元的最長公共子串的長度

演算法沒有優化:

狀態轉移方程:f[i][j] = f[i-1][j-1] + 1 (a[i] == b[i])

f[i][j] = max(f[i-1][j],f[i][j-1]) (a[i] != b[i])

輸入樣例:

abcfbc abfcab

programming contest

abcd mnp

輸出樣例:42

0 ac

*/ #define n 1001

#define max(a,b) ((a)>(b)?(a):(b))

string a,b;

int lena,lenb;

int f[n][n];

int main()elseelse}}

}dfs1(lena,lenb);//輸出乙個公共子串

cout<4.lcs的應用,最長公共子串行的輸出(hdu1503 advanced fruits)

#include#include#include#include#include#includeusing namespace std;

#define n 1001

string a,b,ab;

int lena,lenb,lenab;

int dp[n][n];

int vis[n][n];

void dfs2(int la,int lb)

if(vis[la][lb] == 1)elseelse}}

}dfs2(lena,lenb);

cout<}

return 0;

}

最長公共子串行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 表示...