1143 最長公共子串行 動態規劃

2021-10-04 23:41:26 字數 1924 閱讀 3479

給定兩個字串 text1 和 text2,返回這兩個字串的最長公共子串行。

乙個字串的 子串行 是指這樣乙個新的字串:它是由原字串在不改變字元的相對順序的情況下刪除某些字元(也可以不刪除任何字元)後組成的新字串。

例如,「ace」 是 「abcde」 的子串行,但 「aec」 不是 「abcde」 的子串行。兩個字串的「公共子串行」是這兩個字串所共同擁有的子串行。

採用動態規劃的策略,與最大上公升子串行長度的動態規劃解法不同的是,採用了二維的dp 陣列(**) 而非一維dp陣列。

狀態定義:

為了表示方便,先舉例:

text1 = "abcd"

text2 = "ace"

dp table\「」

「a」「b」

「c」「d」「」0

0000

「a」011

11「c」011

22「e」011

22橫軸、縱軸分別表示兩個字串的各個字元, 其中從第一列(行)表示空串的情況。

d p[

i][j

]dp[i][j]

dp[i][

j]表示text2的前i個字元子串和text1的前j個字元字串的lcs(longest common string)長度。邊界狀態:當其中乙個為空串時,其lcs值必為0。

狀態轉移方程:

d p[

i+1]

[j+1

]=dp

[i][

j]+1

ifte

xt1[

i+1]

==te

xt2[

j+1]

dp[i+1][j+1] =dp[i][j]+1 \ if \ text1[i+1]==text2[j+1]

dp[i+1

][j+

1]=d

p[i]

[j]+

1ift

ext1

[i+1

]==t

ext2

[j+1]dp

[i+1

][j+

1]=m

ax(d

p[i]

[j+1

],dp

[i+1

][j]

)ift

ext1

[i+1

]!=t

ext2

[j+1

]dp[i+1][j+1] =max(dp[i][j+1], dp[i+1][j]) if \ text1[i+1]\ != text2[j+1]

dp[i+1

][j+

1]=m

ax(d

p[i]

[j+1

],dp

[i+1

][j]

)ift

ext1

[i+1

]!=t

ext2

[j+1

]簡單的理解就是:在已知兩個字串的lcs的前提下,同時往兩個字串後新增乙個字元,如果該兩字元相等,則說明新的字串對的lcs長度為 原lcs長度值加1。如果給兩個字元不相等,向上、向左相鄰的lcs值中兩者較大值。向左(或向上)相鄰的lcs值 等價於 在已知兩個字串的lcs值前提下,向其中乙個字串新增乙個字母,那麼新的lcs值就有兩種可能,要麼不變,要麼加1。

int longestcommonsubsequence(string text1, string text2) 

} // dp table最後乙個位置即為lcs值。

int lcs = dp[length_t1][length_t2];

return lcs;

}

最長公共子串行 動態規劃

經常會遇到複雜問題不能簡單地分解成幾個子問題,而會分解出一系列的子問題。簡單地採用把大問題分解成子問題,並綜合子問題的解匯出大問題的解的方法,問題求解耗時會按問題規模呈冪級數增加。為了節約重複求相同子問題的時間,引入乙個陣列,不管它們是否對最終解有用,把所有子問題的解存於該陣列中,這就是動態規劃法所...

最長公共子串行 動態規劃

關於用動態規劃法求兩個序列的最長公共子串行問題的相關知識見 王曉東 計算機演算法設計與分析 第三章。注意,這裡所指的最長公共子串行是可以不相鄰的,與平常所說的最長公共子串 相鄰的 不一樣。直接上 lcs.h ifndef lcs h define lcs h class lcstring endif...

最長公共子串行(動態規劃)

定義 乙個數列 如果分別是兩個或多個已知數列的子串行,且是所有符合此條件序列中最長的,則 稱為已知序列的最長公共子串行。考慮最長公共子串行問題如何分解成子問題,設a a0,a1,am 1 b b0,b1,bm 1 並z z0,z1,zk 1 為它們的最長公共子串行。不難證明有以下性質 1 如果am ...