3136: 动态规划基础题目之最长公共子序列
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 82 Solved: 45
[ Submit][ Status][ Web Board]
Description
给出两个字符串,求出这样的一 个最长的公共子序列的长度:子序列 中的每个字符都能在两个原串中找到, 而且每个字符的先后顺序和原串中的 先后顺序一致。数据保证每个字符串均在100个以内。
Input
多组输入,一行输入两个字符串
Output
输出最长公共子序列。
Sample Input
abcfbc abfcab
programming contest
abcd mnp
Sample Output
4
2
0
HINT
abcfbc abfcab最长的公共子序列为:abcb,所以输出4
Source
【解析】:dp[i][j]表示左边前i个和右边前j个字符的最大公共序列,当左边与右边无字符时序列为0,第一个字符相等时序列为1,第二个字符相等时序列加一,字符不等时,序列长度为(左边前i-1个数和右边前j个数的最大序列)与(左边前i个数和右边前j-1个数的最大序列)中的最大值。可以写出递推公式:
if (s1[i - 1] == s2[j - 1])
dp[i][j] = dp[i - 1][j - 1] + 1;
else
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
【AC代码】:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
/**输入左边的序列*/
String s = sc.next();
char s1[] = new char[100];
int n1 = s.length();
for (int i = 0; i < n1; i++)
s1[i] = s.charAt(i);
/**输入右边的序列*/
String ss = sc.next();
char s2[] = new char[100];
int n2 = ss.length();
for (int i = 0; i < n2; i++)
s2[i] = ss.charAt(i);
/**计算*/
int dp[][] = new int[100][100];
for (int i = 1; i <= n1; i++) {
for (int j = 1; j <= n2; j++) {
if (s1[i - 1] == s2[j - 1])
dp[i][j] = dp[i - 1][j - 1] + 1;
else
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
System.out.println(dp[n1][n2]);
}
}
}