Search
Duplicate
🙆🏻‍♀️

LCS 2

주차
12
문제번호
9252
언어
C++
티어
골드
유형
DP
nj_Blog
nj_상태
이해도
풀이
사람
이해도 2
13 more properties

1. 문제 풀이

모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 문제이다.
처음에는 일치하는 문자열을 찾아 char 배열에 저장 한 뒤 바로 출력하는 방식으로 풀어보려 했지만
구현이 복잡해져 정확히 먼저 수를 구한 뒤 가장 긴 수열을 찾아 역추적하는 방식으로 풀었다...
문자열은 알파벳 대문자로만 이루어져 있으며, 최대 1000글자로 이루어져 있다.
우선 1000자를 담을 수 있는 이차원배열을 0으로 초기화 한뒤 문자가 일치할 시에 이전에 일치한 개수에
1을 더해가는 방식으로 구현했다.
아래 표를 보면 일치하는 문자를 만나면 이전 인덱스의 값에 + 1을 하고
result[i][j] = result[i - 1][j - 1] + 1;
C++
복사
불일치 하면 그대로 i와 j 중 더 큰 값을 넣어 줌으로 긴 카운트를 이어가도록 했다.
max(result[i][j - 1], result[i - 1][j]);
C++
복사
표에는 나와있지 않지만 코드 상 이전 인덱스를 카운트 하기 위해 0번 인덱스는 비우고 1번 부터 배열을 채워갔다.
두개의 문자열 비교가 끝나면 마지막 인덱스가 곧 가장 긴 문자열의 길이가 된다.
해당 길이 만큼의 문자열 배열을 선언, 가장 긴 문자열의 인덱스를 찾는 규칙을 찾아보면
현재 인덱스의 result[i][j - 1] , result[i - 1][j] 보다 큰 숫자 일때이고 만약 result[i - 1][j] 와 현재 인덱스가 같다면 이미 해당라인은 동일한 것이 없음으로 i—로 올라가게 된다.
더할 문자를 찾았으면 배열에 문자열을 추가하고 추가한 j 열 부터는 사용할 수 없기에 len = j - 1로 변경해준다.

2. 코드

#include <iostream> #include <algorithm> #include <cstring> using namespace std; int main(int argc, char const *argv[]) { //길이를 잴 이차원 배열 0초기화 int result[1001][1001] = {0,}; char one[1001]; char two[1001]; cin >> one; cin >> two; int i_len = strlen(one); int j_len = strlen(two); for (int i = 1; i <= i_len; i++) { for (int j = 1; j <= j_len; j++) { //문자 일치할시 이전 대각선 값 + 1 if (one[i - 1] == two[j - 1]) result[i][j] = result[i - 1][j - 1] + 1; else result[i][j] = max(result[i][j - 1], result[i - 1][j]); } } cout << result[i_len][j_len] << endl; //역추적으로 공통 문자열 구하기 if (result[i_len][j_len] > 0) { char r[result[i_len][j_len] + 1]; int z = result[i_len][j_len] - 1; int len = j_len; for (int i = i_len; i >= 0; i--) { if (result[i][len] == 0) break ; for (int j = len; j >= 0; j--) { if (result[i][j] == result[i - 1][j]) break ; if (result[i][j] != result[i][j - 1]) { r[z--] = two[j - 1]; len = j - 1; break ; } } } r[result[i_len][j_len]] = '\0'; cout << r << endl; } return 0; }
C++
복사

3. 채점 기록

메모리 : 5812KB / 시간 : 4ms