一、题目
二、分析
比较基础的求最长升序子序列。
$DP[i][j]$表示的是字符串$S1[1...i]$与$S2[1...j]$的最长公共子序列长度。
状态转移:$$if s1[i] == s2[j] DP[i][j] = DP[i-1][j-1] + 1$$ $$if s1[i] != s2[j] DP[i][j] = max(DP[i-1][j], DP[i][j-1]$$
相等时好理解,不相等的时候就是考虑两个字符串分别加上这个字符后,最长的公共子序列长度。
三、AC代码
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <vector> 6 #include <cmath> 7 8 using namespace std; 9 #define ll long long 10 #define Min(a,b) ((a)>(b)?(b):(a)) 11 #define Max(a,b) ((a)>(b)?(a):(b)) 12 const int MAXN = 1e3; 13 char s[MAXN+13], s2[MAXN+13]; 14 int DP[MAXN+13][MAXN+13]; 15 16 int main() 17 { 18 while(scanf("%s%s", s, s2) != EOF) { 19 memset(DP, 0, sizeof(DP)); 20 int L1 = strlen(s), L2 = strlen(s2); 21 for(int i = 1; i <= L1; i++) { 22 for(int j = 1; j <= L2; j++) { 23 if(s[i-1] == s2[j-1]) { 24 DP[i][j] = DP[i-1][j-1] + 1; 25 } 26 else { 27 DP[i][j] = Max(DP[i-1][j], DP[i][j-1]); 28 } 29 } 30 } 31 printf("%d\n", DP[L1][L2]); 32 } 33 return 0; 34 }