9252번: LCS 2
LCS(Longest Common Subsequence, 최장 공통 부분 수열)문제는 두 수열이 주어졌을 때, 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 문제이다. 예를 들어, ACAYKP와 CAPCAK의 LCS는 ACAK가 된다.
www.acmicpc.net
LCS 길이를 구하는건 이전에 풀어봤던 LCS 문제들과 같았기 때문에 쉽게 구할 수 있었다.
필자는 LCS를 출력하기 위해 pair<int, string> 형태로 값을 저장했는데 시간초과가 발생하였다.
원인은 정확히 모르겠으나 문자열 길이를 비교하기 위해 string 문자열을 매개변수로 받는 max 함수를 호출하면서 string 복사생성자와 소멸자를 많이 호출하게 되어 그만큼 시간이 늘어난 것이라 생각한다.
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
string strA, strB, strRes;
int memo[1001][1001];
int max(int a, int b) { return a > b ? a : b; }
int Length(int hereA, int hereB)
{
if (hereA == strA.length() || hereB == strB.length())
return 0;
int& ret = memo[hereA][hereB];
if (ret != -1) return ret;
ret = 0;
int same = strA[hereA] == strB[hereB]; // 같으면 1 다르면 0
ret = max(Length(hereA + 1, hereB), max(Length(hereA, hereB + 1), Length(hereA + 1, hereB + 1) + same));
return ret;
}
void Str(int hereA, int hereB)
{
if (hereA == strA.length() || hereB == strB.length())
return;
if (strA[hereA] == strB[hereB])
{
strRes += strA[hereA];
Str(hereA + 1, hereB + 1);
}
else if (memo[hereA + 1][hereB] >= memo[hereA][hereB + 1])
Str(hereA + 1, hereB);
else
Str(hereA, hereB + 1);
}
int main(void)
{
memset(memo, -1, sizeof(memo));
cin >> strA >> strB;
int res = Length(0, 0);
cout << res << endl;
if (res != 0)
{
Str(0, 0);
cout << strRes << endl;
}
return 0;
}
알고리즘 200일 프로젝트 - 98 day
'알고리즘 > BOJ' 카테고리의 다른 글
백준 11049번: 행렬 곱셈 순서 (0) | 2020.07.14 |
---|---|
백준 2011번: 암호코드 (0) | 2020.07.12 |
백준 10942번: 팰린드롬? (0) | 2020.07.09 |
백준 2096번: 내려가기 (0) | 2020.07.09 |
백준 11066번: 파일 합치기 (0) | 2020.07.08 |