반응형
250x250
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- nodeJS
- 몰입캠프후기
- html
- 자바스크립트
- MySQL
- 위상정렬
- BFS
- 분리집합
- 타입스크립트
- 궁동
- 어은동맛집
- 앱개발
- 카이스트
- 후기
- 리사이클러뷰
- glfw
- DP
- node.js
- 안드로이드스튜디오
- 백준
- 자바
- 프로그래머스
- 컴퓨터그래픽스
- computergraphics
- 대전맛집
- 카이스트맛집
- 프래그먼트
- 몰입캠프
- 우선순위큐
- 알고리즘
Archives
- Today
- Total
소근소근
[백준 BOJ 17218 glod5 - 비밀번호 만들기] Longest Common String (LCS) C++ 본문
728x90
반응형
SMALL
백준 17218 https://www.acmicpc.net/problem/17218
이렇게 두개의 문자열에서 가장 긴 공통 수열을 찾고, 그 수열을 출력해야 하는 문제이다.
2차원 배열을 이용한 dp로 해결할 수 있다.
#include <string>
#include <vector>
#include <algorithm>
#include <queue>
#include <tuple>
#include <string>
#include <string.h>
#include <iostream>
using namespace std;
int alpha[41][41];
char str1[41];
char str2[41];
int back[41][41];
vector <char> LCS;
void backtracking(int x, int y) { //백트래킹
if (x <= 0 || y <= 0) return;
if (back[x][y] == 1) backtracking(x, y - 1);
else if (back[x][y] == 2) backtracking(x - 1, y);
else if (back[x][y] == 3) {
LCS.push_back(str2[x]);
backtracking(x - 1, y - 1);
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
string s1;
string s2;
cin >> s1 >> s2;
int M = s1.length();
int N = s2.length();
for (int i = 0; i < s1.length(); i++) {
str1[i+1] = s1[i];
}
for (int i = 0; i < s2.length(); i++) {
str2[i + 1] = s2[i];
}
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
if (str1[j] == str2[i]) {
alpha[i][j] = alpha[i-1][j-1]+ 1;
back[i][j] = 3; //왼쪽위에
}
else {
alpha[i][j] = max(alpha[i - 1][j], alpha[i][j - 1]);
int up = alpha[i - 1][j];
int left = alpha[i][j - 1];
if (up == left || left > up) back[i][j] = 1; //왼쪽
else if (up > left) back[i][j] = 2; //위쪽
}
}
}
backtracking(N, M);
for (int i = LCS.size() - 1; i >= 0; i--) {
cout << LCS[i];
}
}
S | E | T | A | P | P | L | E | |
E | 0 | 1 | 1 (k) | 1 | 1 | 1 | 1 | 1 |
A | 0 | 1 | 1 (a) | 2 (b) | ||||
T | ||||||||
M | ||||||||
A | ||||||||
N | ||||||||
Y | 3 |
(a) : T와 A는 다르므로, dp[i-1][j]와 dp[i][j-1] 중에서 더 큰 값을 가져온다. 즉, 현재 위치에서 위쪽, 왼쪽 값을 비교해서 더 큰 값을 가져온다. 같을 경우에는 왼쪽에서 가져오게 했다. (이때 값을 가져오는 방향을 또 다른 하나의 배열에 저장한다. 공통 수열을 출력하기 위해 후에 백트래킹에 필요하다. 이 코드의 경우 back 배열이다)
(b) : A == A , 같은 알파벳일때는 dp[i-1][j-1] + 1 을 넣어준다. 즉 이 표에서는 (k) 값 +1 을 (b)에 넣어준다.
dp[N][M] 에 있는 수가 두 수열의 가장 긴 공통 수열의 길이가 된다.
이 문제에서는 길이가 아니라 공통 수열을 출력해야 하므로 표를 채우면서 저장했던 값 가져오는 방향을 이용한다. dp[N][M] 에서부터 방향대로 백트래킹을 하면서, (b)처럼 값을 갱신한 경우의 알파벳을 저장하면 LCS가 된다.
728x90
반응형
LIST
'Algorithm' 카테고리의 다른 글
[백준 BOJ 13711 glod1 - LCS4] Longest Common String (LCS) C++ (0) | 2022.01.04 |
---|---|
C++ upper_bound , lower_bound 이용하기 / 알고리즘 (0) | 2022.01.04 |
[백준 BOJ 3665 gold1 - 최종 순위] 위상정렬(topological sort) C++ (0) | 2021.12.31 |
[백준 BOJ 2056 gold4 - 작업] 위상정렬(topological sort) C++ (0) | 2021.12.31 |
[백준 BOJ 1516 gold3 - 게임 개발] 위상정렬(topological sort) C++ (0) | 2021.12.31 |