題目不說了,學習dp時候經典的例子。如果現在有兩個序列x = 和y = ,他們的lcs是z = 。下面分兩種情況討論:
1) 如果xm = yn,那麼一定有zk = xm = yn,即xm與yn相等時他們一定是lcs結尾的那個元素。lcs(x, y) = lcs(x', y') + xm。
2)如果xm != yn,那麼zk != xm 和zk != yn至少有乙個成立。則lcs(x, y) = max,其中x'和y'是x和y剔除最右邊元素而得到的序列。
從上面的討論可以得到狀態轉移方程:
圖是我盜的,c[i, j]表示x序列前i項和y序列前j項的lcs的長度。
下面是**,可以用滾動陣列優化下空間複雜度。
#include #include int max(int a, int b)
int main()
for(i = 1; i <= len1; i++)
else
}} printf("%d\n", dp[len1][len2]);
} return 0;
}
/*如果只計算長度空間複雜度可以優化到o(n),因為填矩陣時候每次存當前這行和上面那行就夠了。
除非你要得到最優子串行。*/
#include #include int max(int a, int b)
int main()
for(i = 1; i <= len1; i++)
else
}} printf("%d\n", dp[len1 %2][len2]);
} return 0;
}
其實這篇文章講的挺詳細的,尤其是怎麼求lcs還有優化的細節。 poj 1458 最長公共子串行
common subsequence 題意 一行給出兩個字串s1和s2,找出他們的最長 公共子串行數量,乙個金典的動態規劃問題。用dp i j 表示字串s1取前i個,字串s2取前j個時,他們的最長公共子串行數量有多少。當s2右端又加入了乙個字元時,即表示為dp i j 1 時,如果s1 i 和s2 ...
POJ1458最長公共子串行
為了完成poj中的一題 spell checker 要寫乙個最長公共子串行的程式,居然突然全給忘了,楞是沒有寫出來,深深的鄙視自己一下。這也是一道動態規劃的典型題。遞迴實現如下 poj提交會超時,但是確實可以實現 using namespace std define max a b a b a b ...
POJ 1458 最長公共子串行
這個題的意思就是說 給乙個序列 a 和 b 讓你求他們的共同的子串行的長度,這些子串行可以不在原來的字串中連續排列。這個題的話,我們可以使用動態規劃的思路,我們假設 maxlen i j 是 a 串和 b 串中從一開始的,a 串中的的第 i 個字元和b 串中的第 j 個字元的最長公共子串行的長度。我...