https://www.acmicpc.net/problem/9252
9252번: LCS 2
LCS(Longest Common Subsequence, 최장 공통 부분 수열)문제는 두 수열이 주어졌을 때, 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 문제이다. 예를 들어, ACAYKP와 CAPCAK의 LCS는 ACAK가 된다.
www.acmicpc.net
저는 해당 문제를 DP를 이용하여 문제를 해결하였습니다.
2차원 DP[y][x]를 통해 a의 y번째 글자와 b의 x번째 글자를 비교해 같다면
DP[y][x] = (DP[y-1][x] , DP[y][x-1] , DP[y-1][x-1] + 1) 중 최대값,
둘의 글자가 다르다면
DP[y][x] = (DP[y-1][x] , DP[y][x-1] , DP[y-1][x-1] ) 중 최대값으로 초기화하였습니다.
최종 글자는 역순으로 둘의 글자가 같다면 대각선으로 다르다면 위쪽이나 아래쪽으로 이동해 같은 글자라면 결과에 문자를 추가하는 방법으로 해결하였습니다.
package BOJ.DP;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class BOJ_9252 {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String a = br.readLine();
String b = br.readLine();
int[][] dp = new int[a.length()][b.length()];
for(int i = 0 ; i < a.length() ; i++){
for(int j = 0 ; j < b.length() ; j++){
int isSame = 0;
if(a.charAt(i) == b.charAt(j)){
isSame = 1;
}
int result = isSame;
if(i != 0){
result = Math.max(result, dp[i-1][j]);
}
if(j != 0){
result = Math.max(result, dp[i][j-1]);
}
if(i != 0 && j != 0 ){
result = Math.max(result, dp[i-1][j-1] + isSame);
}
dp[i][j] = result;
}
}
System.out.println(dp[a.length()-1][b.length()-1]);
int y = a.length()-1;
int x = b.length()-1;
int prev = 0;
StringBuilder sb = new StringBuilder();
while(y >= 0 && x >= 0){
if(a.charAt(y) == b.charAt(x)){
sb.append(a.charAt(y));
y--;
x--;
}else if(y-1 < 0){
x--;
}else if(x-1 < 0){
y--;
}else if(dp[y-1][x] > dp[y][x-1]){
y--;
}else{
x--;
}
}
System.out.println(sb.reverse().toString());
}
}
'알고리즘' 카테고리의 다른 글
백준 1368번 물대기 (JAVA) (0) | 2022.03.09 |
---|---|
백준 11967번 불켜기 (JAVA) (0) | 2022.03.08 |
프로그래머스 표 편집 (JAVA) (0) | 2022.03.06 |
프로그래머스 거리두기 확인하기(JAVA) (0) | 2022.03.05 |
프로그래머스 숫자 문자열과 영단어(JAVA) (0) | 2022.03.05 |