繼續用典型問題來討論動態規劃的兩個特性(重疊子問題和最優子結構)。最長公共子串行(lcs)問題描述:
給定兩個序列,找出在兩個序列中同時出現的最長子序列的長度。乙個子串行是出現在相對順序的序列,但不一定是連續的。例如,「abc」,「abg」,「bdf」,「aeg」,「acefg「,..等都是」abcdefg「 序列。因此,長度為n的字串有2 ^ n個不同的可能的序列。
注意最長公共子串(longest commonsubstring)和最長公共子串行(longestcommon subsequence, lcs)的區別:子串(substring)是串的乙個連續的部分,子串行(subsequence)則是從不改變序列的順序,而從序列中去掉任意的元素而獲得的新序列;更簡略地說,前者(子串)的字元的位置必須連續,後者(子串行lcs)則不必。比如字串acdfg同akdfc的最長公共子串為df,而他們的最長公共子串行是adf。lcs可以使用動態規劃法解決。
這是乙個典型的電腦科學問題,基礎差異(即輸出兩個檔案之間的差異檔案比較程式),並在生物資訊學有較多應用。
這個問題的直觀的解決方案是同時生成給定序列的所有子串行,找到最長匹配的子串行。此解決方案的複雜性是指數的。讓我們來看看如何這個問題 (擁有動態規劃(dp)問題的兩個重要特性):
以下為l(x [0 .. m-1],y [0 .. n-1])的遞迴定義:
如果兩個序列的最後乙個元素匹配(即x [m-1] == y [n-1])
l(x [0 .. m-1],y [0 .. n-1])= 1 + l(x [0 .. m-2],y [0 .. n-1])
如果兩個序列的最後字元不匹配(即x [m-1]!= y [n-1])
l(x [0 .. m-1],y [0 .. n-1])= max(l(x [0 .. m-2],y [0 .. n-1]),l(x [0 .. m-1],y [0 .. n-2])
例子:1)考慮輸入字串「aggtab」和「gxtxayb」。最後乙個字元匹配的字串。這樣的lcs的長度可以寫成:
l(「aggtab」, 「gxtxayb」) = 1 + l(「aggta」, 「gxtxay」)
2)考慮輸入字串「abcdgh」和「aedfhr。最後字元不為字串相匹配。這樣的lcs的長度可以寫成:
l(「abcdgh」, 「aedfhr」) = max ( l(「abcdg」, 「aedfhr」), l(「abcdgh」, 「aedfh」) )
因此,lcs問題有最優子結構性質!
#include #include #include #include using namespace std;
const int maxn = 100;
char a[maxn], b[maxn];
int lcs(int m, int n)
int main()
return 0;
}
如果我們繪製完整的遞迴樹,那麼我們可以看到,我們可以看到很多重複的呼叫。
所以這個問題有重疊的子結構性質,我們可以用迭**:
int lcs(int m, int n)
} return dp[m][n];
}
#include #include #include #include using namespace std;
const int maxn = 100;
char a[maxn], b[maxn], ans[maxn];
int dp[maxn][maxn];
//int lcs(int m, int n)
//int lcs(int m, int n)
} return dp[m][n];
}void build_lcs(char* ans, int m, int n) }}
int main()
return 0;
}
DP 最長公共子串行
解題報告 題目 演算法 dp 最長公共子串行 思路 最長公共子串行,英文縮寫為lcs longest common subsequence 其定義是,乙個數列 s 如果分別是兩個或多個已知數列的子串行,且是所有符合此條件序列中最長的,則 s 稱為已知序列的最長公共子串行。d i j 表示s1的第i位...
最長公共子串行 DP
有序子串行定義 若x 則它的子串行為y 即原序列調出若干項組成的序列且下標要求有序。lcs 最長公共子串行 定義 給定兩個序列x 和y 存在乙個嚴格遞增的x的下標序列為,對所有的j 1,2,3.k,滿足xi yj,例如x 1 4 3 2 5 y 4 3 5 7 則x和y的最長公共子串行為 4 3 5...
最長公共子串行 DP
最長公共子串行 lcs.pas c cpp 問題描述 乙個給定序列的子串行是在該序列中刪去若干元素後得到的序列。確切地說,若給定序列x x1,x2,xm 則另一串行z z1,z2,zk 是x的子串行是指存在乙個嚴格遞增的下標序列 i1,i2,ik 使得對於所有j 1,2,k有 xij zj 例如,序...