반응형

문제링크:https://www.acmicpc.net/problem/5582

 

5582번: 공통 부분 문자열

문제 두 문자열이 주어졌을 때, 두 문자열에 모두 포함된 가장 긴 공통 부분 문자열을 찾는 프로그램을 작성하시오. 어떤 문자열 s의 부분 문자열 t란, s에 t가 연속으로 나타나는 것을 말한다. 예

www.acmicpc.net

 

공통 부분 문자열을 찾는 문제입니다. n의 범위가 4000까지입니다.

 

일반적인 구현방법을 생각해볼때 O(n^3)이 됩니다. 이때 최악의 경우 64,000,000,000 번 반복되기에 당연히 시간초과입니다.

 

n^2 번의 계산법을 찾아야합니다. 

 

저는 표를 만들어 보며 규칙을 찾았습니다. 

  A A B C A W
A 1 1 0 0 1 0
B 0 0 1 0 0 0
C 0 0 0 1 0 0
A 1 1 0 0 1 0

 

보이시나요? 이전 배열값에서 1을 더한 값이 자신의 최대연속배열값입니다.

 

점화식은 dp[i][j] = dp[i - 1][j - 1] + 1 입니다. 

 

  A A B C A W
A 1 1 0 0 1 0
B 0 0 2 0 0 0
C 0 0 0 3 0 0
A 1 1 0 0 4 0

 

 

 

정답코드입니다.

#include <iostream>
#include <string>
using namespace std;
string arr;
string arr2;
int dp[4001][4001] = { 0 };
int result = 0;
int main() {
	cin >> arr;
	cin >> arr2;

	for (int j = 0; j < arr2.size(); j++) {
		if (arr[0] == arr2[j]) {
			dp[0][j] = 1;
			if (result < dp[0][j]) result = dp[0][j];
		}
	}

	for (int j = 0; j < arr2.size(); j++) {
		if (arr[j] == arr2[0]) {
			dp[j][0] = 1;
			if (result < dp[j][0]) result = dp[j][0];
		}	
	}


	for (int i = 1; i < arr.size(); i++) {
		for (int j = 1; j < arr2.size(); j++) {
			if (arr[i] == arr2[j]) {
				dp[i][j] = dp[i - 1][j - 1] + 1;
				if (result < dp[i][j]) result = dp[i][j];
			}
		}
	}
	cout << result << endl;

}
반응형

'알고리즘 > DP' 카테고리의 다른 글

[백준] 2602-돌다리 건너기(C++)  (0) 2020.06.10
[백준] 1695-팰린드롬 만들기(C++)  (0) 2020.05.20
[백준] 5557-1학년(C++)  (0) 2020.05.17
[백준] 2096-내려가기(C++)  (0) 2020.05.08
[백준] 1915-가장 큰 정사각형(C++)  (0) 2020.05.03

+ Recent posts