给定两个长度分别为N和M的字符串A和B,求既是A的子序列又是B的子序列的字符串长度最长是多少。
输入格式
第一行包含两个整数N和M。
第二行包含一个长度为N的字符串,表示字符串A。
第三行包含一个长度为M的字符串,表示字符串B。
字符串均由小写字母构成。
输出格式
输出一个整数,表示最大长度。
数据范围
1≤N≤10001≤N≤1000,
输入样例:
4 5 acbd abedc
输出样例:
3
解答:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
in.nextLine();
char[] s1 = in.nextLine().toCharArray();
char[] s2 = in.nextLine().toCharArray();
//dp[i][j]的含义是:s1[0-i]和s2[0-j]的最长公共子序列
int[][] dp = new int[n][m];
//初始化,两个字符串的第一个字符是否相等
dp[0][0] = s1[0] == s2[0] ? 1 : 0;
//初始化,把第一行和第一列进行初始化,由于判断的是子序列,所以
//只要有一个字符相等,后面的dp就都是1
for (int i = 1; i < n; i++) {
dp[i][0] = Math.max(dp[i - 1][0], s1[i] == s2[0] ? 1 : 0);
}
for (int i = 1; i < m; i++) {
dp[0][i] = Math.max(dp[0][i - 1], s1[0] == s2[i] ? 1 : 0);
}
for (int i = 1; i < n; i++) {
for (int j = 1; j < m; j++) {
//默认情况,dp[i][j]应该是将s1或者s2去掉一个字符后的dp的较大值
dp[i][j] = Math.max(dp[i][j - 1],dp[i - 1][j]);
//若s1[i]==s2[j],还需要判断和dp[i - 1][j - 1] + 1比较后的较大值
if (s1[i] == s2[j]) {
dp[i][j] = Math.max(dp[i][j],dp[i - 1][j - 1] + 1);
}
}
}
System.out.println(dp[n - 1][m - 1]);
}
} 
京公网安备 11010502036488号