動態規劃經典問題 最長公共子串行(LCS)

2021-06-03 21:24:42 字數 2070 閱讀 9089

什麼是子串行呢?子串行就是從給定的序列中隨意的(不一定是連續的)去掉若干個元素(也可能乙個也不去掉)後所形成的序列。如x=abcbdab,y=bcdb就是x的乙個子串行。

最長公共子串行問題描述為:給定序列x=x1x2x3x4...xm,   y=y1y2y3y4...yn. 求出序列x和y的最長公共子串行z。

我們首先想到了用窮舉法,首先列舉出序列x的所有子串行,並一一檢測是不確y的子串行,並設定乙個變數來記錄當前的最長公共子串行,這種方法比較直觀,但是當序列為長序列的時候,這種方法耗費的時間將是非常可觀的,需要指數級時間。而利用動態規劃將可以有效的解決這個問題。

那應該如何利用動態規劃法呢?從哪開始思考?   我們還記得,要看乙個問題是否能夠用動態規劃法,首先要看此問題是否具有最優子結構特徵,那好,我們用從這裡開始入手。下面的定理證明了lcs的最優子結構(這個定理具體是怎麼來的,如何證明的可看看相關書籍)。

定理:設給定序列x=x1x2x3x4...xm,   y=y1y2y3y4...yn.  z=z1z2z3...zk是x和y的乙個最長公共子串行。

1,如果xm==yn,那麼zk==xm==yn,而z=z1z2z3...zk-1是序列x=x1x2x3x4...xm-1,   y=y1y2y3y4...yn-1.的乙個最長公共子串行,這裡要注意:兩個序列的公共子串行並不是唯一的,可能有多個

2,如果xm!=yn,這樣就有三種情況,1),最長公共子串行包括xm,zk==xm,這個時候就要去除yn,因為既然包括了xm,而且這是序列的最後乙個元素,所以,必定不包含yn,這樣最長公共子串行就成了求序列x=x1x2x3x4...xm,   y=y1y2y3y4...yn-1.的乙個最長公共子串行  .2)  最長公共子串行包括yn,zk==yn,這個時候就要去除xm,因為既然包括了yn,而且這是序列的最後乙個元素,所以,必定不包含xm,這樣最長公共子串行就成了求序列x=x1x2x3x4...xm-1,   y=y1y2y3y4...yn.的乙個最長公共子串行.  3) 最長公共子串行兩個都不包括zk!=xm!=yn,這種情況,去掉哪乙個都一樣(這種情況用處不大)。

那要怎麼設計程式呢?題目要求是求最長公共子串行,那我們就要記錄在一步步遍歷子問題過程中所求的當前最長序列長度。

我們假設x,y的最長公共子串行為lcs[m,n];根據上面的定理,我們寫出狀態轉移方程:lcs[m,n]=max

這樣看來,我們在進行求解的過程中就在決定兩個序列中哪乙個元素要放入最長公共子串行中。那麼該怎麼決定呢,就是根據上面的方程lcs[m,n]=max。。

我們知道,動態規劃方法本質就是遍歷所有可能的子問題,最終求解到子問題。這裡的子問題是什麼呢,根據上面分析,就是i(0=所以我們應該定義乙個二維陣列來表示i長度的序列和j長度的序列的最長子序列長度。lcs[m][n].   x序列是行,y序列是列。

需要注意的是當某乙個序列的長度為0時,那麼當前最優值為0。

下面是核心**

for(int i=0;i<8;++i)

length[0][i]=0;

for(i=0;i<7;++i)

length[i][0]=0;

for(i=1;i<7;++i)

else

else

}}

我們每當計算某乙個子問題時,都要把它想象成是最終的問題。這樣才能更好的運用之前的狀態轉移方程,因為我們這個方程就是從後往前給推出來的

上邊**中的flag是為了在求出最優解之後,然後構造最優解儲存的資訊。那需要儲存哪些資訊才有助於我們構造呢。根我們前面分析,我們需要從後往前來推測某乙個元素是不是最長公共子串行中的元素,只要看看if(xm==yn).如果相等的話,說明這是本次序列中的乙個公共序列的最後乙個元素,如果不等的話,那就往前遞推,以相同的規則來構造前乙個子問題的最優解。這很明顯可以設計成乙個遞迴結構。所以我們儲存了如上所述資訊

我們可以構造下面的遞迴函式:

void output(int flag[7][8],int i,int j,char x[6])

{ if(i==0 || j==0)

return ;

if(flag[i][j]==0)

{  output(flag,i-1,j-1,x);

cout《問題解決了,發現這個問題有點像0-1揹包問題。.。

動態規劃經典 最長公共子串行

最長公共子串行 時間限制 3000 ms 記憶體限制 65535 kb 難度 3 描述 咱們就不拐彎抹角了,如題,需要你做的就是寫乙個程式,得出最長公共子串行。tip 最長公共子串行也稱作最長公共子串 不要求連續 英文縮寫為lcs longest common subsequence 其定義是,乙個...

動態規劃 最長公共子串行問題

最長公共子串行問題 longest common subsequence problem 簡稱lcs問題。題目為給定兩個序列x y求它們的lcs 最長公共子串行 這裡的子串行z的定義為 z中的元素既在x中也在y中,並且他們在x y中滿足嚴格的下標為乙個增序列 假設下標從左到右依次增大 另外,不要求z...

最長公共子串行問題 動態規劃

給定兩個字串s1s2.sn和t1t2.tn。求出這兩個字串最長的公共子串行 輸入 abcicba abdkscab 輸出 abca 定義dp i j 為s1 si和t1 tj對應的lcs的長度 s1 si 1和t1 tj 1對應的公共子列有三種情況 當si 1 tj 1時,在s1 si和t1 tj的...