f[i][j]表示a的前i个字母,和b的前j个字母的最长公共子序列的长度
集合划分4中情况:
1. a[i]不在,b[j]也不在 => f[i][j] = f[i - 1][j - 1]
2. a[i]不在,b[j]在 => f[i][j] = f[i - 1][j];
3. a[i]在,b[j]不在 => f[i][j] = f[i][j - 1];
4. a[i]在,b[j]在 => f[i][j] = f[i - 1][j - 1] + 1;
对于第1种情况 包含在了2、3中情况:
仔细看会发现:对于2、3情况实际上状态表示大了,f[i - 1][j]表示的是
在a的前i - 1个字母中和b的j个字母中选择最长公共子序列,但是实际上
b[j]不一定会选到,因此2情况包括1情况,3情况同理
第4中情况选择时有前提条件:a[i] == b[j]
import java.util.*;
public class Main {
static final int N = 1010;
static char[] A = new char[N], B = new char[N];
static int[][] f = new int[N][N];
static int n, m;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] nm = sc.nextLine().split(" ");
n = Integer.parseInt(nm[0]);
m = Integer.parseInt(nm[1]);
A = sc.nextLine().toCharArray();
B = sc.nextLine().toCharArray();
for (int i = 1; i <= n; i ++) {
for (int j = 1; j <= m; j++) {
f[i][j] = Math.max(f[i - 1][j], f[i][j - 1]);
//这里因为的的字符串下标是从0开始的所有减1
if (A[i - 1] == B[j - 1]) f[i][j] = Math.max(f[i][j], f[i - 1][j - 1] + 1);
}
}
System.out.println(f[n][m]);
}
}