메모리: 18968 KB, 시간: 136 ms
다이나믹 프로그래밍, 문자열
2025년 1월 4일 20:15:55
LCS(Longest Common Subsequence, 최장 공통 부분 수열)문제는 두 수열이 주어졌을 때, 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 문제이다.
예를 들어, ACAYKP와 CAPCAK의 LCS는 ACAK가 된다.
첫째 줄과 둘째 줄에 두 문자열이 주어진다. 문자열은 알파벳 대문자로만 이루어져 있으며, 최대 1000글자로 이루어져 있다.
첫째 줄에 입력으로 주어진 두 문자열의 LCS의 길이를, 둘째 줄에 LCS를 출력한다.
LCS가 여러 가지인 경우에는 아무거나 출력하고, LCS의 길이가 0인 경우에는 둘째 줄을 출력하지 않는다.
/**
* Author: yngbao97, Yuk Yejin
* Problem: LCS 2_9252
* Date: 2025.01.04
*/
import java.util.*;
import java.lang.*;
import java.io.*;
public class Main {
static BufferedReader br;
static BufferedWriter bw;
static StringTokenizer st;
public static void main(String[] args) throws Exception {
br = new BufferedReader(new InputStreamReader(System.in));
bw = new BufferedWriter(new OutputStreamWriter(System.out));
char[] A = br.readLine().toCharArray();
char[] B = br.readLine().toCharArray();
int[][] lcs = new int[A.length+1][B.length+1];
for (int i = 0; i < A.length; i++) {
for (int j = 0; j < B.length; j++) {
if (A[i] == B[j]) lcs[i+1][j+1] = lcs[i][j] + 1;
else lcs[i+1][j+1] = Math.max(lcs[i][j+1], lcs[i+1][j]);
}
}
Stack<Character> word = new Stack<>();
int i = A.length-1;
int j = B.length-1;
while (i >= 0 && j >= 0) {
if (A[i] == B[j]) {
word.push(A[i]);
i--;
j--;
} else {
if (lcs[i+1][j] >= lcs[i][j+1]) j--;
else i--;
}
}
bw.write(String.valueOf(word.size()) + "\n");
while (!word.isEmpty()) bw.write(word.pop());
bw.flush();
bw.close();
br.close();
}
}