給定兩個序列x和y,稱z是x和y的公共子串行,如果z既是x的子串行,又是y的子串行;最長的公共子串行稱作最長公共子串行lcs(longest common subsequence)。
(1)lcs的最優子結構
設zk是xm和yn的乙個lcs,則,如果x和y的最後乙個元素相同,則z中去掉最後乙個元素之後zk-1仍為xm-1和yn-1的lcs。
如果xm!=yn,若zk!=xm,則z是xm-1和y的乙個lcs,若zk!=yn,則z是xm和yn-1的lcs。
(2)乙個遞迴解
設c[i][j]為序列xi和yj的乙個lcs的長度,則有:
expression
conditionc[
i][j
]=0i=0或j=0c[
i][j
]=c[
i−1]
[j−1
]+1xi=yj且i,j>0c[
i][j
]=ma
x(c[
i][j
−1],
c[i−
1][j
])xi!=yj且i,j>0
(3)計算lcs的長度
#include
#include
#include
using
namespace
std;
int lenlcs(const
char *ch1, const
char *ch2, int len1, int len2, int **c)
for (int i = 0; i <= len2; i++)
for (int i = 1; i <= len1; i++)
else
else}}
}// for (int i = 0; i <= len1; i++)
// for (int j = 0; j <= len2; j++)
// if (j == len2) printf("%d\n", c[i][j]);
// else printf("%d ", c[i][j]);
return c[len1][len2];
}void printlcs(const
char *ch1, const
char* ch2, int len1, int len2, int **c)
else
else}}
}int main()
cout
delete c;
return
0;}
不連續情況的轉移方程:
擴充套件到連續情況,轉移方程為:
實現**如下:
#include
#include
#include
using
namespace
std;
int fun(char *ch1, char *ch2, int len1, int len2, int **c)
for (int j = 0; j <= len2; j++)
int maxlen = 0;
for (int i = 1; i <= len1; i++)
else
maxlen = max(maxlen, c[i][j]);}}
return maxlen;
}int main()
int maxlen = fun(ch1, ch2, len1, len2, c);
printf("the max length is : %d\n", maxlen);
for (int i = 0; i <= len1; i++)
delete c;
}
動態規劃之最長公共子串行
最長公共子串行簡介 舉例說明並分析 塊測試結果 乙個給定序列的子串行是在該序列中刪去若干元素後得到的序列,確切的說,若給定序列x 則另一串行z x的子串行是指存在乙個嚴格的下標序列,使得對於所有的j 0,1,k 1有zj xij。例如序列z 是序列x 的子串行,相應的遞增下標序列維。最長公共子串行問...
動態規劃之最長公共子串行
給出兩個字串,求出這樣的一 個最長的公共子串行的長度 子串行 中的每個字元都能在兩個原串中找到,而且每個字元的先後順序和原串中的 先後順序一致。sample input abcfbc abfcab programming contest abcd mnp sample output 4 2 0對於動...
動態規劃之最長公共子串行
最長公共子串行問題 time limit 1000 ms memory limit 65536 kib submit statistic discuss problem description 給定兩個序列x input 輸入資料有多組,每組有兩行 每行為乙個長度不超過500的字串 輸入全是大寫英文...