51nod1006最長上公升子串行(求路徑)

2021-07-11 13:31:43 字數 1283 閱讀 5951

這道題目以前完全用char寫,現在在嘗試用string去寫,感覺還不錯,思路如下:

我們用ax表示序列a的連續前x項構成的子串行,即ax= a1,a2,……ax, by= b1,b2,……by, 我們用lcs(x, y)表示它們的最長公共子串行長度,那原問題等價於求lcs(m,n)。為了方便我們用l(x, y)表示ax和by的乙個最長公共子串行。

讓我們來看看如何求lcs(x, y)。我們令x表示子串行考慮最後一項

(1) ax = by

那麼它們l(ax, by)的最後一項一定是這個元素!

為什麼呢?為了方便,我們令t = ax = by, 我們用反證法:假設l(x,y)最後一項不是t,

則要麼l(x,y)為空序列(別忘了這個),要麼l(x,y)的最後一項是aa=bb ≠ t, 且顯然有a < x, b < y。無論是哪種情況我們都可以把t接到這個l(x,y)後面,從而得到乙個更長的公共子串行。矛盾!

如果我們從序列ax中刪掉最後一項ax得到ax-1,從序列by中也刪掉最後一項by得到by-1,(多說一句角標為0時,認為子串行是空序列),則我們從l(x,y)也刪掉最後一項t得到的序列是l(x – 1, y - 1)。為什麼呢?和上面的道理相同,如果得到的序列不是l(x - 1, y - 1),則它一定比l(x - 1, y - 1)短(注意l(,)是個集合!),那麼它後面接上元素t得到的子串行l(x,y)也比l(x - 1, y - 1)接上元素t得到的子串行短,這與l(x, y)是最長公共子串行矛盾。

因此l(x, y) = l(x - 1, y - 1) 最後接上元素t

lcs(ax, by) = lcs(x - 1, y - 1) + 1

這道題不好寫的地方是路徑的那塊,我們要乙個字元陣列倒著記錄,然後再倒著輸出

#include 

#include

#include

using

namespace

std;

int dp[1005][1005];

char s[1005];

string a,b;

int main()

int k=0;

while(dp[p][q])

else

if(dp[p][q]!=dp[p-1][q-1])

}for(int i=k-1;i>=0;i--)

cout

a.clear();

for(int i=0;i<=b.length();i++)

b.clear();

}return

0;}

51Nod 1006 最長公共子串行Lcs(DP)

給出兩個字串a b,求a與b的最長公共子串行 子串行不要求是連續的 比如兩個串為 abcicba abdkscab ab是兩個串的子串行,abc也是,abca也是,其中abca是這兩個字串最長的子串行。input 第1行 字串a 第2行 字串b a,b的長度 1000 output 輸出最長的子串行...

51nod 1006 最長公共子串行Lcs

給出兩個字串a b,求a與b的最長公共子串行 子串行不要求是連續的 比如兩個串為 abcicba abdkscab ab是兩個串的子串行,abc也是,abca也是,其中abca是這兩個字串最長的子串行。input 第1行 字串a 第2行 字串b a,b的長度 1000 output 輸出最長的子串行...

51nod1006 最長公共子串行Lcs

思路 定義dp i j 為a串以i結尾,b串為j結尾的子串行的最長公共子串行長度,則 if a i a j dp i j dp i 1 j 1 1,else dp i j max dp i 1 j dp i j 1 這題的話 還需要記錄長度為dp i j 的公共子串行選自哪些位置,詳情看 ac 我的...