作業9 動態規劃之LCS問題

2021-10-05 08:15:39 字數 1787 閱讀 5149

求兩個已知序列的最長公共子串行,乙個序列的子串行滿足下標嚴格遞增。

如果zk 是 xi 和 yj 的最長公共子串行(下標表示該序列的長度)

則有以下三點規則:

(1) 如果x[i] = y[j],那麼z[k] = x[i] =y[j],zk-1 是 xi-1 和 yj-1 的最長公共子串行;

(2) 如果x[i] ≠ y[j],z[k] ≠ x[i] ,那麼zk 是 xi-1 和 yj 的最長公共子串行;

(3) 如果x[i] ≠ y[j],z[k] ≠ y[j] ,那麼zk 是 xi 和 yj-1 的最長公共子串行;

得出演算法遞推關係:

c[i][j]表示x序列前i個元素和y序列前j個元素的最長公共子串行長度(int), i < xlen, j < ylen

c[i][j] = c[i-1][j-1] + 1 , x[i] = y[j]

c[i][j] = max, x[i] != y[j]

c[i][j] 存放兩個序列的最長公共子串行的長度

b[i][j] 存放兩個序列與[i-1],[j-1]兩個序列的關係

stack,存放子串行的棧

初始化:c[0][j] 和c[i][0]都為0

for i < xlen

for j < ylen

if(x[i]==y[j]) c[i][j] = c[i-1][j-1] +1 b[i][j] = 『2』;

else c[i][j] = c[i-1][j] >= c[i][j-1] ? c[i-1][j] : c[i][j-1] b[i][j] =『x』 || 『y』

for i = xlen, j = ylen; i>0 && j>0

if (b[i][j] == 『x』) i–;

else if (b[i][j] == 『y』) j–;

else stack.push(x[i]) i-- j–

逐個pop stack;

t = o(xlen * ylen)

#include

#include

#include

#include

using namespace std;

#define xlen 5

#define ylen 4

void

getlcs

(char x,

char y)

for(

int j =

0; j < ylen; j++

)for

(int k =

1; k <= xlen; k++

)else

if(c[k -1]

[l]>= c[k]

[l -1]

)else}}

printf

("%d\n"

, c[xlen]

[ylen]);

for(

int i = xlen,j = ylen;j >

0&& i >0;

)}while

(!s.

empty()

)}intmain()

x[i]

= ch;

}for

(int i =1;

; i++

) y[i]

= ch;

}getlcs

(x, y)

;return0;

}

LCS問題 動態規劃

簡述 lcs問題,即最長公共子串行問題,給定兩個序列x 和y 求x y最長的公共子串行。與lis類似,lcs也是可以不連續的。解題思路 本人覺得在這個問題上演算法導論講的很好,所以在此我主要是整理。1 首先我們來考慮暴力搜尋求解的方法,我們要暴力列舉x的所有子串行,然後再看看是不是也是y的子串行,這...

動態規劃解LCS問題

今天研究了一下動態規劃,思想很簡單 循序漸進,區域性推到整體。但運用起來還是不太好想的。下面用動態規劃解lcs最大公共子串問題 寫了兩個函式lcs和lcs inhance,前者用矩陣實現 用於理解原理 後者用兩個陣列實現 節省空間 如下 include includeusing namespace ...

動態規劃之LCS演算法

lcs是longest common subsequence的縮寫,即最長公共子串行。乙個序列,如果是兩個或多個已知序列的子串行,且是所有子串行中最長的,則為最長公共子串行。另外還有個分支問題 最長公共子串。子串的字元位置必須連續,而子串行則不必,從原序列中去掉任意的元素獲得的新序列。可以看出,子串...