51NOD 最長公共子串行問題

2021-08-02 10:25:14 字數 1348 閱讀 2179

給出兩個字串a b,求a與b的最長公共子串行(子串行不要求是連續的)。

比如兩個串為:

abcicba

abdkscab

ab是兩個串的子串行,abc也是,abca也是,其中abca是這兩個字串最長的子串行。

輸入

第1行:字串a

第2行:字串b

(a,b的長度 <= 1000)

輸出

輸出最長的子串行,如果有多個,隨意輸出1個。
輸入示例

abcicba

abdkscab

輸出示例

abca
求解:

引進乙個二維陣列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的情況,此時開始返回。返回時與遞迴呼叫時方向相反,步數相同,故演算法時間複雜度為o(m + n)。

#include#include#include using namespace std;

long int c[1001][1001];

int main()

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

for(j=1;j<=n2;j++)

c[i][j]=(a[i-1]==b[j-1])?(c[i-1][j-1]+1):max(c[i][j-1],c[i-1][j]);

for(i=n1,j=n2;i>=1&&j>=1;)

else

else}}

for(i=k-1;i>=0;i--)cout<

cout<

return 0;

}

51NOD 最長公共子串行問題

最長公共子串行問題就是求序列a a1,a2,an,和b b1,b2,bm,的乙個最長公共子串行。因為最長公共子串行不唯一,讓我們把問題簡化,如何求出兩個序列的最長公共子串行長度呢?你首先能想到的恐怕是暴力列舉?那我們先來看看 序列a有 2 n 個子序列,序列b有 2 m 個子序列,如果任意兩個子串行...

51nod 最長公共子串行測試 LCS 回溯

輸入 第1行 字串a 第2行 字串b a,b的長度 1000 輸出 輸出最長的子串行,如果有多個,隨意輸出1個。輸入示例 abcicba abdkscab 輸出示例 abca 這道題比較6,但是利用每個位置的記錄進行回溯就更6,好好體會下。include include include includ...

51nod動態規劃入門 最長公共子串行

題目 給出兩個字串a b,求a與b的最長公共子串行 子串行不要求是連續的 輸入 第1行 字串a 第2行 字串b a,b的長度 1000 輸出 輸出最長的子串行,如果有多個,隨意輸出1個。輸入示例 abcicba abdkscab 輸出示例 abca 如下 include include includ...