반응형
rolypolytoy
현's story
rolypolytoy
전체 방문자
오늘
어제
  • 분류 전체보기
    • 현's tory
      • 여행
      • 개인사업
      • 컨프런스
      • 채용지원
    • Vision AI | 3D Graphics
      • Vision AI
      • OpenGL
    • 프로그래밍 언어
      • C++
      • Python
    • Computer Science
      • 운영체제
    • 알고리즘
      • 백준
      • 프로그래머스
      • 개념정리
    • 유용한 링크
      • 개발

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 알고리즘
  • c++
  • 알고리즘구현
  • 백준2302
  • 프로그래머스실패율
  • iOS비동기
  • 백준2533
  • 백준다이나믹
  • 상표특허출원
  • vscodeopengl
  • 다이나믹프로그래밍
  • DFS조합
  • PlantUML
  • 아키텍처패턴
  • 디자인패턴
  • 백준17471
  • IOS
  • 백준13397
  • openglvscode
  • 백준문제풀이
  • 백준
  • 백준2169
  • 백준사회망서비스
  • iOSMetal
  • 사회망서비스
  • 백준1756
  • 백준알고리즘
  • EffectiveC++
  • 백준이분탐색
  • sync

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
rolypolytoy

현's story

[백준 9252] LCS 2 C++
알고리즘/백준

[백준 9252] LCS 2 C++

2021. 1. 21. 20:46
반응형

www.acmicpc.net/problem/9252

 

9252번: LCS 2

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

www.acmicpc.net

 

 

 

LCS 2는 LCS 1를 응용한 문제입니다.

 

LCS 2를 풀기위해서, LCS 1의 과정을 이해해야합니다.

rolypolytoy.tistory.com/43?category=365766

 

[백준 9251] LCS C++

www.acmicpc.net/problem/9251 9251번: LCS LCS(Longest Common Subsequence, 최장 공통 부분 수열)문제는 두 수열이 주어졌을 때, 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 문제이다. 예를 들어, ACAY..

rolypolytoy.tistory.com

 

 

LCS 1을 이해하셨다면, LCS 2는 문자열을 찾는 알고리즘을 삽입하면 됩니다.

 

찾는 알고리즘은 LCS 1을 구현한 것을 반대로 재귀 호출을 한다음, return 하면서 해당하는 문자 값을 출력하시면 됩니다.

 

LCS 1에서 a[i-1] == b[j-1]이라면 dp[i][j] = d[i-1][j-1] + 1 (1의 의미는, 공통 문자 하나 찾았다는 의미)

으로 구했기 때문에, 반대로,

i, j의 인덱스가 dp[i][j] 위치에 있을 때,

a[i-1] == b[j-1] 의 조건이 만족이 된다면, a[i-1][j-1]이 공통 부문 문자열 중 하나이기 때문에 그 칸으로 다시 재귀 호출을 합니다.

 

a[i-1] != b[j-1]의 경우, LCS를 구할 때 dp 배열의 왼쪽, 위쪽 배열 중 최댓값을 취했기 때문에,

반대로 문자열을 찾아갈 때도, dp의 왼쪽, 오른쪽 중에 최대값으로 다시 재귀호출을 하여 찾아가면됩니다. 

 

그렇게 되면 재귀호출은 항상 a[i-1] == b[j-1]에서 모든 호출이 끝나고 난 뒤에,

a[i-1]이나 b[j-1]을 호출하게 된다면, return으로 반환하면서 우리가 찾고 싶어하는 LCS의 문자열을 찾을 수 가 있습니다.

저한테 DP 사용과 재귀호출로 반대로 찾아가는 것이 처음에 어렵다고 느껴졌습니다. 하지만, 왜 이런 결과가 나왔는지에 대해

차근차근 생각해보고 다른 블로그나 개념들을 읽어보면서 이해하시면 개념이 조금씩 보이기 시작한다고 생각합니다.

 

오늘도 좋은 하루 되세요^^ 

#include <iostream>
#include <algorithm>
#include <string>
#include <vector>

using namespace std;

const int MAX = 1001;

int dp[MAX][MAX];

string a, b;
void find(int i, int j){
    if (dp[i][j] == 0) return; // LCS 값이 없을 땐 출력하지 않기

    if (a[i-1] == b[j-1]){ // 이전의 문자가 같다면, 해당 인덱스로 재귀호출하기
        find(i-1, j-1);
        cout << a[i-1]; // a[i-1] 혹은 b[i-1] 둘 중 하나 출력하기
    } else dp[i-1][j] > dp[i][j-1] ? print(i-1, j) : print(i, j-1);
    // a, b중에서 LCS가 더 큰 값으로 재귀함수 호출하기
}
void solution(){

    
    cin >> a >> b;

    int a_size = a.length();
    int b_size = b.length();

    for (int i = 1; i <= a_size; i++)
        for (int j = 1; j <= b_size; j++){
            if (a[i-1] == b[j-1]) {
                dp[i][j] = dp[i-1][j-1] + 1;
            }
            else dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
        }
	// LCS 1처럼 LCS 값 찾기
    

    cout << dp[a_size][b_size] << '\n';
    
	// a_size, b_size위치부터 거꾸로 문자를 찾아가기.
    find(a_size, b_size);
}
int main(){

    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    solution();

    return 0;
}

 

반응형
저작자표시 비영리 변경금지 (새창열림)

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

[백준 17471] 게리맨더링 C++  (0) 2021.01.22
[백준 2169] 로봇 조종하기 C++  (0) 2021.01.22
[백준 9251] LCS C++  (0) 2021.01.21
[백준 2096] 내려가기 C++  (0) 2021.01.21
[백준 1707] 이분 그래프 C++  (0) 2021.01.11
    '알고리즘/백준' 카테고리의 다른 글
    • [백준 17471] 게리맨더링 C++
    • [백준 2169] 로봇 조종하기 C++
    • [백준 9251] LCS C++
    • [백준 2096] 내려가기 C++
    rolypolytoy
    rolypolytoy

    티스토리툴바