簡述: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...