LCS問題 動態規劃

2021-06-29 10:02:00 字數 1128 閱讀 1392

簡述:lcs問題,即最長公共子串行問題,給定兩個序列x=和y=,求x、y最長的公共子串行。與lis類似,lcs也是可以不連續的。

解題思路:本人覺得在這個問題上演算法導論講的很好,所以在此我主要是整理。

1、首先我們來考慮暴力搜尋求解的方法,我們要暴力列舉x的所有子串行,然後再看看是不是也是y的子串行,這樣的方法,顯然時間複雜度是指數級的,所以並不可取,但是,我們是否能從中看到些什麼呢?

2、我們來看看lcs是不是具有最優子結構:

之前說的暴力求解,在程式中怎麼表達呢?考慮乙個序列z=,他是x、y的乙個lcs序列:

如果xm==yn,就意味著xm肯定在z序列裡,而且是zk;

如果xm!=yn,那麼說明xm和yn至多有乙個在z裡面,所以這裡x、y的lcs就有兩種可能性:x(1…m-1)與y(1…n)的lcs和x(1…m)與y(1…n-1)的lcs;

於是有最優子結構!

3、從上面就可以看出來了,沒錯,就是深搜!但是,太慢了。所以,記憶化一下就行了!

於是……用dp[i][j]表示x(1…i)和y(1…j)的lcs,那麼有狀態轉移方程

if(x[i]==y[j])

dp[i][j]=dp[i-1][j-1]+1;

else

dp[i][j]=max(dp[i-1][j],dp[i][j-1]);

完整**:(可以用poj_1458測試一下)

#include 

#include

#include

#include

using namespace std;

int m,n,x[1005],y[1005],ans,dp[1005][1005];

char st1[1005],st2[1005];

int main()

}printf("%d\n",dp[m][n]);

}return 0;

}

總結:

1、之前一直不知道lcs是啥,今天算是了解了一下;

2、果然深搜是王道啊!

動態規劃解LCS問題

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

動態規劃 LCS計算

int findlcs string a,int n,string b,int m dp的第一行 for int j 0 j m 1 j 其他位置的dp值 for int i 1 i n 1 i else dp i j dp i 1 j dp i j 1 dp i 1 j dp i j 1 retu...

作業9 動態規劃之LCS問題

求兩個已知序列的最長公共子串行,乙個序列的子串行滿足下標嚴格遞增。如果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...