最長公共子串行 動態規劃

2021-06-19 13:06:27 字數 1185 閱讀 2689

經常會遇到複雜問題不能簡單地分解成幾個子問題,而會分解出一系列的子問題。簡單地採用把大問題分解成子問題,並綜合子問題的解匯出大問題的解的方法,問題求解耗時會按問題規模呈冪級數增加。

為了節約重複求相同子問題的時間,引入乙個陣列,不管它們是否對最終解有用,把所有子問題的解存於該陣列中,這就是動態規劃法所採用的基本方法。

【問題】

求兩字串行的最長公共字元子串行

求解:引進乙個二維陣列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]。

問題的遞迴式寫成:

回溯輸出最長公共子串行過程:

演算法分析:

由於每次呼叫至少向上或向左(或向上向左同時)移動一步,故最多呼叫(m + n)次就會遇到i = 0或j = 0的情況,此時開始返回。返回時與遞迴呼叫時方向相反,步數相同,故演算法時間複雜度為θ(m + n)。

利用求最長公共子串行求單調遞增最長子序列**:

#include#include#include#include#includeusing namespace std;

char str[27];

int istr;

int l[10005][27];//長度length

void lcs_l(char a[10005],char b[27])

}void lcs_str(char a[10005],char b[27],int i,int j)

else if(l[i-1][j]>l[i][j-1])

else

lcs_str(a,b,i,j-1);

}int main(void)

// system("pause");

return 0;

}

參考:

最長公共子串行 動態規劃

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

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

問題描述 使用動態規劃演算法解最長公共子串行問題,具體來說就是,依據其遞迴式,自底向上的方式依次計算得到每個子問題的最優值。輸入形式 在螢幕上輸入兩個序列x和y,序列各元素數間都以乙個空格分隔。輸出形式 矩陣c,其中c i,j 中存放的是 序列xi 和序列yj 的最長公共子串行的長度。序列x和y的最...