一、题目
二、分析
比较基础的求最长升序子序列。
$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 }