對於什麼是子串行和公共子串行,這裡不再進行贅述,直接切入主題。
首先遇到這類問題,可能會首先想到窮舉進行畢竟,但是窮舉出乙個長度為n的串的子串行,有2的n次方種情況,那麼對於時間複雜度將會是指數級的,所以需要用dp的思想進行求解。
我們先設兩個字串a,b
ax為前x個連續字元組成的子串行,同理可得by的含義。
那麼比較ax和by的最後乙個字元ax和by
情況一:ax == by
那麼ax和by一定是ax和by的最長公共子串行的最後乙個字元,所以我們只需要求lcs(ax - 1,by - 1)的最長公共子串行 + 1即可得出lcs(ax,by)。
情況二:ax != by
那麼ax和by的最長公共子串行的最後一位一定滿足 t != ax || t != by,那麼我們就只需要求出max( lcs( ax - 1,by ),lcs( ax,by - 1 ) )即是ax和by的最大公共子串行。
由情況一二可得,我們將改任務不斷分解成子任務,就是dp的特徵之一,我們由此可得遞推式
由此可得**(自底向上的dp)
void
lcs(string s1,string s2)
else
if(dpmaxlenth[i -1]
[j]>= dpmaxlenth[i]
[j -1]
)else}}
}
這裡的0既是空序列的最大公共子串行數為0。
若要使對程式執行的過程進行直觀和詳細的解釋可以參考這位博主的文章 傳送門
因為後面在進行求具體某乙個最長公共子串行的時候,如果不清楚程式過程的話,對我來說,會有些困難。
這裡先給出乙個模板題common subsequence
單純的求最大公共子串行的長度
**如下
#include
#include
#include
using
namespace std;
int dpmaxlenth[
1005][
1005];
void
lcs(string s1,string s2)
else
if(dpmaxlenth[i -1]
[j]>= dpmaxlenth[i]
[j -1]
)else}}
}int
main()
return0;
}
對於求具體的最長公共子串行,首先我們要知道,有時候解不唯一,所以我們求任意乙個即可
如圖,即從終點進行回溯。
例題1006 最長公共子串行lcs
#include
#include
#include
using
namespace std;
int dpmaxlenth[
1005][
1005];
void
lcs(string s1,string s2)
else
if(dpmaxlenth[i -1]
[j]>= dpmaxlenth[i]
[j -1]
)else}}
}void
llcs
(string s1,string s2)
else
if(dpmaxlenth[i -1]
[j]< dpmaxlenth[i]
[j -1]
)else
}for
(int z = k; z >=
1; z--
) cout<
}int
main()
return0;
}
DP 最長公共子串行 LCS
題目 poj 1458 題目簡述 求兩個字串的最長公共子串行的長度。題目分析 這是一道經典的lcs問題,用dp來解決。include include include define mem x memset x 0,sizeof x define maxn 10 1000 using namespac...
dp 最長公共子串行 LCS
給定兩個字串 text1 和 text2,返回這兩個字串的最長公共子串行。乙個字串的 子串行 是指這樣乙個新的字串 它是由原字串在不改變字元的相對順序的情況下刪除某些字元 也可以不刪除任何字元 後組成的新字串。例如,ace 是 abcde 的子串行,但 aec 不是 abcde 的子串行。兩個字串的...
dp 最長公共子串行(LCS)
字串行 與 字元字串的區別 序列是可以不連續的字串 字串必須要是連續的 問題描述 給定兩串字串 abcde 和 acdf 找出 2 串中相同的字串行,觀察知 相同的字串行為 acd 方法一 暴力解決 對於乙個長度為 n 的串 它的字串總共有 2 n 個,在用著 2 n 個字串與另乙個長度為 m 的串...