문제 풀이/Baekjoon Online Judge
[Baekjoon Online Judge] 9251번: LCS
hyeonic
2021. 1. 8. 20:18
9251번: LCS
LCS(Longest Common Subsequence, 최장 공통 부분 수열)문제는 두 수열이 주어졌을 때, 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 문제이다. 예를 들어, ACAYKP와 CAPCAK의 LCS는 ACAK가 된다.
www.acmicpc.net
LCS (Longest Common Subsequence)
공통 부분 수열 중 가장 길이가 긴 것이 바로 최장 공통 부분 수열이다. 문제의 예시를 들어보았다.
문자열 A - ACAYKP
문자열 B - CAPCAK
두개의 문자열이 있다고 가정하자. 두 문자열의 공통 부분 수열은 C, CA, ACA, ACAK, AA 등이 있다. 그중 가장 긴 부분 수열을 구하는 문제이다.
문자열 A - ACAYKP
문자열 B - CAPCAK
이렇게 ACAK가 가장 긴 부분 수열이 된다.
LCS의 길이를 구하는 공식은 생각보다 간단하다. 이 공식과 동적 프로그래밍을 사용하여 문제를 해결하였다.
이 공식을 활용하여 테이블을 그려보았다.
0 | A | C | A | Y | K | P | |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
C | 0 | ||||||
A | 0 | ||||||
P | 0 | ||||||
C | 0 | ||||||
A | 0 | ||||||
K | 0 |
우선 i와 j가 0인 배열에 0을 채워준다. 그 뒤로 C와 A, C와 C, C와 A, C와 Y ... 를 비교하며 테이블 값을 채워나간다.
0 | A | C | A | Y | K | P | |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
C | 0 | 0 | 1 | 1 | 1 | 1 | 1 |
A | 0 | 1 | 1 | 2 | 2 | 2 | 2 |
P | 0 | 1 | 1 | 2 | 2 | 2 | 3 |
C | 0 | 1 | 2 | 2 | 2 | 2 | 3 |
A | 0 | 2 | 2 | 3 | 3 | 3 | 3 |
K | 0 | 2 | 2 | 3 | 3 | 4 | 4 |
import java.io.*;
public class Baekjoon9251 {
private static int[][] dpTable;
private static void LCS(Character x, int i, Character y, int j) {
if (i == 0 || j == 0) dpTable[i][j] = 0;
else if (x == y) {
dpTable[i][j] = dpTable[i - 1][j - 1] + 1;
} else if (x != y) {
dpTable[i][j] = Math.max(dpTable[i][j - 1], dpTable[i - 1][j]);
}
}
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(System.out));
String a = "0" + bufferedReader.readLine();
String b = "0" + bufferedReader.readLine();
dpTable = new int[a.length()][b.length()];
for (int i = 0; i < dpTable.length; i++) {
for (int j = 0; j < dpTable[0].length; j++) {
LCS(a.charAt(i), i, b.charAt(j), j);
}
}
bufferedWriter.write(String.valueOf(dpTable[a.length() - 1][b.length() - 1]));
bufferedWriter.flush();
bufferedReader.close();
bufferedWriter.close();
}
}