목록으로

기술 노트

[C/C++][DP] 백준 9252번: LCS 2

문제: https://www.acmicpc.net/problem/9252 두 문자열을 각각 가로축, 세로축으로 두고 문자열이 같은 부분에서 문자열 길이를 담은 DP배열에 +1해준다.그 다음 인덱스는 전 단계에서 얻어진 DP배열에서 큰 값을 얻는다. 점화식a[i] == b[i] 일 때 dp[i][j] = dp[i-1][j-1] + 1그렇지 않을 때, dp[i][j]…

2024. 06. 21.0

문제: https://www.acmicpc.net/problem/9252

두 문자열을 각각 가로축, 세로축으로 두고 문자열이 같은 부분에서 문자열 길이를 담은 DP배열에 +1해준다.

그 다음 인덱스는 전 단계에서 얻어진 DP배열에서 큰 값을 얻는다.

점화식

a[i] == b[i] 일 때 dp[i][j] = dp[i-1][j-1] + 1

그렇지 않을 때, dp[i][j] = max(dp[i][j-1], dp[i-1][j])

LCS 문자열을 구하는 과정은 점화식을 거슬러 올라가면 된다.

a[i] == b[i] 일 때 dp[i-1][j-1] 출력 후 이동

그렇지 않을 때, dp[i][j-1] 과 dp[i-1][j] 중에 큰 값 출력 이동

문자열을 역추적 해서 올라갔으므로 재귀 호출을 먼저하여 출력을 나중에 하면 순방향 문자열이 나온다.

#include <iostream>
#include <algorithm>
using namespace std;

int dp[1002][1002];
string a;
string b;

void dprint(int i,int j){
  if(dp[i][j]==0) return ;

  if(a[i-1]==b[j-1]){
    dprint(i-1,j-1);
    cout << a[i-1];
  }
  else{
    if(dp[i-1][j]>dp[i][j-1]){
      dprint(i-1,j);
    }
    else dprint(i,j-1);
  }
}
int main(){
  cout.tie(NULL);
  cin.tie(NULL);
  ios_base::sync_with_stdio(false);
  //

  cin >> a >> b;

  for(int i=0;i<a.size();++i){
    for(int j=0;j<b.size();++j){
      dp[i][j]=0;
    }
  }
  for(int i=0;a[i];++i){
    for(int j=0;b[j];++j){
      if(a[i]==b[j])dp[i+1][j+1]=dp[i][j]+1;
      else dp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);
    }
  }
  cout<<dp[a.size()][b.size()]<<'\n';
  dprint(a.size(),b.size());
  return 0;
}

댓글 0

loading comments...

[C/C++][DP] 백준 9252번: LCS 2