[문제 링크]

 

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

+ Recent posts