ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준]9251: LCS(java)
    Algorithm/백준 2022. 3. 23. 21:53
    728x90

    https://www.acmicpc.net/problem/9251

    문제

    LCS(Longest Common Subsequence, 최장 공통 부분 수열)문제는 두 수열이 주어졌을 때, 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 문제이다.

    예를 들어, ACAYKP와 CAPCAK의 LCS는 ACAK가 된다.

    입력

    첫째 줄과 둘째 줄에 두 문자열이 주어진다. 문자열은 알파벳 대문자로만 이루어져 있으며, 최대 1000글자로 이루어져 있다.

    출력

    첫째 줄에 입력으로 주어진 두 문자열의 LCS의 길이를 출력한다.

    예제 입력 1

    ACAYKP
    CAPCAK
    

    예제 출력 1

    4

    풀이

    dp문제이다. dp배열을 담는 과정은 다음과 같이 생각할 수 있다.

    자가 현재 서로 같은가? 같다면 +1을 해줘야한다.

    처음 C가 같은 순간이다.

    이 이후 왜 A, Y, K, P는 C와 다르지만 왜 1이 될까? 는 위 그림을 참고하면 쉽게 이해할 수 있다.

    우린 가장 긴 부분 수열을 찾기 때문에 이미 C와 같은 순간 그 뒤에는 모두 일치하지 않아도 답은 1이 되기때문이다.

    조금 더 쉽게 단어가 ACAYKP / C 라고 생각하면 쉽게 이해할 수 있다.

    위 과정은 다음과 같은 코드로 해결할 수 있다.

    이경우도 위의 경우와 같다. A와 같은 순간 A 외의 문자는 같지 않아도 반드시 1이상을 가져야한다.

    단어 A / CAPCAK 인 경우로 이해하면 쉽게 이해할 수 있다.

     

    여기서 의문 만약 이미 같은 단어가 나온 후 같은 단어를 찾으면 어떻게 처리해줘야할까? 정답은 아래와 같다.

    여기서 우리는 이미 C가 같았고 그 후에 A가 또 같은 경우를 만나게 된다.

    C가 선택 된 순간

    위 과정을 반복하면 아래와 같다.

    위 과정을 반복하는 코드는 아래와 같다.

    for(int i=1; i<=N; i++) {
        for(int j=1; j<=M; j++) {
            if(str1.charAt(j-1) == str2.charAt(i-1)) {
                dp[i][j] = dp[i-1][j-1] + 1;
            } else {
                dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
            }
        }
    }

    전체 코드

    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    
    public class bJ_G5_9251_LCS {
        public static void main(String[] args) throws Exception{
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    
            String str1 = br.readLine();
            String str2 = br.readLine();
    
            int M = str1.length();
            int N = str2.length();
            int[][]dp = new int[N+1][M+1];
    
            for(int i=1; i<=N; i++) {
                for(int j=1; j<=M; j++) {
                    if(str1.charAt(j-1) == str2.charAt(i-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.printf("%d", dp[N][M]);
        }
    }
    

     

     

    728x90

    'Algorithm > 백준' 카테고리의 다른 글

    [백준]1039: 교환(java)  (0) 2022.03.26
    [백준]17135: 캐슬 디펜스  (0) 2022.03.25
    [백준]12865: 평범한 배낭  (0) 2022.03.24
    [백준]14500: 테트로미노(java)  (0) 2022.03.22
    [백준]2866: 문자열 잘라내기(java)  (0) 2022.03.21

    댓글

Designed by Tistory.