1 분 소요

1. 문제

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

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

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

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

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

// 예제 입력 1
ACAYKP
CAPCAK

// 예제 출력 1
4


2. 핵심 아이디어

  • 두 수열이 주어졌을 때, 두 수열 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾아야 함
  • 가장 긴 공통 부분 수열(LCS) 문제로 알려진 대표적인 DP 문제
  • 두 수열의 길이가 N 미만일 때, 시간 복잡도 O(N^2)으로 문제를 해결할 수 있음
  • D(i)(j) = X(0…i)와 Y(0…j)의 공통 부분 수열의 최대 길이
  • 두 문자열의 길이를 조금씩 늘려 가며 확인하여, 공통 부분 수열의 최대 길이 계산
  • D(i)(j)
    • D(i-1)(j-1) + 1 => if X(i) = Y(j)
    • max(D(i)(j-1), D(i-1)(j)) => if X(i) != Y(j)

baekjoon-9251


3. Python 문제풀이

import sys
input = sys.stdin.readline

x = input().rstrip()
y = input().rstrip()
dp = [[0] * (len(y) + 1) for _ in range(len(x) + 1)]

for i in range(1, len(x) + 1) :
  for j in range(1, len(y) + 1) :
    if x[i - 1] == y[j - 1] :
      dp[i][j] = dp[i - 1][j - 1] + 1
    else :
      dp[i][j] = max(dp[i][j - 1], dp[i - 1][j])

print(dp[len(x)][len(y)])


4. Java 문제풀이

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

class Main {
  static char[] str1;
  static char[] str2;
  static Integer[][] dp;

  public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    str1 = br.readLine().toCharArray();
    str2 = br.readLine().toCharArray();

    dp = new Integer[str1.length][str2.length];
    System.out.println(LCS(str1.length - 1, str2.length - 1));
  }

  static int LCS(int x, int y) {
    if (x == -1 || y == -1) {
      return 0;
    }

    if (dp[x][y] == null) {
      dp[x][y] = 0;

      if (str1[x] == str2[y]) {
        dp[x][y] = LCS(x - 1, y - 1) + 1;
      } else {
        dp[x][y] = Math.max(LCS(x - 1, y), LCS(x, y - 1));
      }
    }
    return dp[x][y];
  }
}

댓글남기기