首先,動態規劃的關鍵是將之前所計算的結果儲存起來,之後直接呼叫!!!
1.問題描述:
------字串的子串行:是指從該字串中去掉任意多個字元後剩下的字元在不改變順序的情況下組成的新字串。
------最長公共子串行:是指多個字串可具有的長度最大的公共的子串行。
比如:
adbcbd
bdcaba這兩個字串的最長公共子串行是dcb
2.找出最優子結構性質:
考慮最長公共子串行問題如何分解成子問題,設a=「a0,a1,…,am-1」,b=「b0,b1,…,bm-1」,並z=「z0,z1,…,zk-1」為它們的最長公共子串行。不難證明有以下性質:
(1)如果am-1=bn-1,則zk-1=am-1=bn-1,且「z0,z1,…,zk-2」是「a0,a1,…,am-2」和「b0,b1,…,bn-2」的乙個最長公共子串行;
(2)如果am-1!=bn-1,則若zk-1!=am-1,蘊涵「z0,z1,…,zk-1」是「a0,a1,…,am-2」和「b0,b1,…,bn-1」的乙個最長公共子串行;
(3)如果am-1!=bn-1,則若zk-1!=bn-1,蘊涵「z0,z1,…,zk-1」是「a0,a1,…,am-1」和「b0,b1,…,bn-2」的乙個最長公共子串行。
(1)如果:am-1=bn-1,則找「a0,a1,…,am-2」和「b0,b1,…,bm-2」的乙個最長公共子串行。
(2)如果am-1!=bn-1,則要解決兩個子問題,
找出「a0,a1,…,am-2」和「b0,b1,…,bn-1」的乙個最長公共子串行
找出「a0,a1,…,am-1」和「b0,b1,…,bn-2」的乙個最長公共子串行
再取兩者中較長者作為a和b的最長公共子串行。
3.找出遞迴規律求解:
—–引進乙個二維陣列c,用c[i][j]記錄x[i]與y[j] 的lcs 的長度,
—–引進乙個二維陣列b[i][j], 記錄c[i][j]是通過哪乙個子問題的值求得的,以決定搜尋的方向。我們是自底向上進行遞推計算,那麼在計算c[i,j]之前,c[i-1][j-1],c[i-1][j]與c[i][j-1]均已計算出來。此時我們根據x[i] = y[j]還是x[i] != y[j],就可以計算出c[i][j]。
問題的遞迴式寫成:
回溯輸出最長公共子串行過程:
#include#include#includeusing namespace std;
void lcs(char *x,char *y,int m,int n,int c[100],int b[100]) /*遞迴尋找最長公共子串行*/
else if(c[i-1][j]>=c[i][j-1])
else
}}void print(int b[100],char *x,int i,int j)/*遞迴輸出最長公共子串行*/
{ if(i==0 || j==0)
return ;
if(b[i][j]==0)
{print(b,x,i-1,j-1);
cout<
最長公共子串行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)
最長公共子串行也是動態規劃中的乙個經典問題。有兩個字串 s1 和 s2,求乙個最長公共子串,即求字串 s3,它同時為 s1 和 s2 的子串,且要求它的長度最長,並確定這個長度。這個問題被我們稱為最長公共子串行問題。與求最長遞增子串行一樣,我們首先將原問題分割成一些子問題,我們用 dp i j 表示...
動態規劃 最長公共子串行 LCS
動態規劃 最長公共子串行 lcs 題目描述 給定兩個字串 或數字序列 a和b,求乙個字串,使得這個字串是a和b的最長公共部分 子串行可以不連續 如樣例所示,字串 sadstory 與 adminsorry 的最長公共子串行為 adsory 長度為6 動態規劃的解法 令dp i j 表示字串a的i號位...