D - Common Subsequence
阿新 • • 發佈:2020-08-03
求兩個字串的最長公共序列,輸出這個序列的長度。
A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = <x1, x2, ..., xm> another sequence Z = <z1, z2, ..., zk> is a subsequence of X if there exists a strictly increasing sequence <i1, i2, ..., ik> of indices of X such that for all j = 1,2,...,k, xij = zj. For example, Z = <a, b, f, c> is a subsequence of X = <a, b, c, f, b, c> with index sequence <1, 2, 4, 6>. Given two sequences X and Y the problem is to find the length of the maximum-length common subsequence of X and Y.Input
abcfbc abfcab programming contest abcd mnp
Output
4 2 0
列如:abcfbc abfcab
F[i][j]=F[i-1][j-1]+1;(a[i]==b[j])
F[i][j]=max(F[i-1][j],F[i][j-1])(a[i]!=b[j]);
n由於F(i,j)只和F(i-1,j-1), F(i-1,j)和F(i,j-1)有關, 而在計算F(i,j)時, 只要選擇一個合適的順序, 就可以保證這三項都已經計算出來了, 這樣就可以計算出F(i,j). 這樣一直推到f(len(a),len(b))就得到所要求的解了.
LCS演算法:
1、序列str1和序列str2
·長度分別為m和n;
·建立1個二維陣列L[m.n];
·初始化L陣列內容為0
·m和n分別從0開始,m++,n++迴圈:
- 如果str1[m] == str2[n],則L[m,n] = L[m - 1, n -1] + 1;
- 如果str1[m] != str2[n],則L[m,n] = max{L[m,n - 1],L[m - 1, n]}
·最後從L[m,n]中的數字一定是最大的,且這個數字就是最長公共子序列的長度
·從陣列L中找出一個最長的公共子序列。
2、從陣列L中查詢一個最長的公共子序列
i和j分別從m,n開始,遞減迴圈直到i = 0,j = 0。其中,m和n分別為兩個串的長度。
·如果str1[i] == str2[j],則將str[i]字元插入到子序列內,i–,j–;
·如果str1[i] != str[j],則比較L[i,j-1]與L[i-1,j],L[i,j-1]大,則j–,否則i–;(如果相等,則任選一個)
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; int dp[1001][1001]; char s1[1001],s2[1001]; int main() { while(~scanf("%s %s",s1,s2)) { int l1=strlen(s1); int l2=strlen(s2); memset(dp,0,sizeof(dp)); for(int i=1;i<=l1;i++) { for(int j=1;j<=l2;j++) { if(s1[i-1]==s2[j-1]) dp[i][j]=dp[i-1][j-1]+1; else dp[i][j]=max(dp[i-1][j],dp[i][j-1]); } } printf("%d\n",dp[l1][l2]); } }