[ 백준 ] 5582 / 공통 부분 문자열

金弘均·2021년 9월 16일
0

Baekjoon Online Judge

목록 보기
204/228
post-thumbnail

# Appreciation

/*
 * Problem :: 5528 / 공통 부분 문자열
 *
 * Kind :: Dynamic Programming
 *
 * Insight
 * - LCS = Longest Common Subsequence 가 아니라
 *   LCS = Longest Common Substring 이다
 *   + subsequence 는 연속적이지 않은 부분 문자열이고
 *     substring 은 연속적인 부분 문자열이다
 *     # 기존에 알고 있던 위의 LCS 알고리즘을 조금 변경해서 써야할 것 같다
 *
 * - 문자열 u 와 v 가 있을 때
 *   기존 LCS(subsequence) 알고리즘에서는
 *   dp[i][j] = u 의 i 번째 문자까지와 v 의 j 번째 문자까지의 max(len(LCS)) 였다
 *   + 알고리즘은 다음과 같다
 *     if (u[i] == v[i]) { dp[i][j] = dp[i-1][j-1] + 1; }
 *     else { dp[i][j] = max(dp[i][j-1], dp[i-1][j]); }
 *     # 위의 LCS 알고리즘에서 subsequence 가 아니라 substring 의 경우에는
 *       연속되어야 하기 때문에 else 문의 max(dp[i][j-1], dp[i-1][j]) 는 옳지 않다
 *       -> i 번째 문자로끝나는 substring 과 j 번째 문자로끝나는 substring 이어야 하니까
 *       -> 그렇다면 else 문만 빼면 될 것 같은데...? <= 진짜 else 문만 뺐더니 통과했다!
 *          지금생각해보니 u[i] 와 v[j] 가 다르면 dp[i][j] = 0 일 수밖에 없다
 *
 * Point
 * - dp 를 나중에 모두 탐색하면서 최댓값 찾지 귀찮아서
 *   그때그때 값의 갱신이 일어날 때마다 최댓값을 찾아주었다
 *
 * - 편의상 문자열의 첫 번째 글자를 인덱스 0 으로 간주하였다
 *   + 문자열 u 의 i 번째 글자 = u[i-1]
 *     문자열 v 의 j 번째 글자 = V[j-1]
 *
 * - u[i] == v[j] 여서 LCS 에 속한다면
 *   이 글자는 또 다른 LCS 에 동시에 속할 수 없다
 */

# Code

//
//  BOJ
//  ver.C++
//
//  Created by GGlifer
//
//  Open Source

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

#define endl '\n'

// Set up : Global Variables
/* None */

// Set up : Functions Declaration
/* None */


int main()
{
    // Set up : I/O
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    // Set up : Input
    string u; cin >> u;
    string v; cin >> v;

    // Process
    int lu = u.length();
    int lv = v.length();

    /* dp[i][j] = u 의 i 번째 글짜까지와 v 의 j 번째 글짜까지의 max(len(LCS))
     * 여기서 S 는 Subsequence 가 아닌 Substring 을 의미 */
    int dp[lu+1][lv+1];
    memset(dp, 0, sizeof(dp)); /* 초기화 */
    int ans = 0;
    for (int i=1; i<=lu; i++) {
        for (int j=1; j<=lv; j++) {
            if (u[i-1] == v[j-1]) {
                dp[i][j] = dp[i-1][j-1]+1;
                ans = max(ans, dp[i][j]);
            }
        }
    }

    // Control : Output
    cout << ans << endl;
}

// Helper Functions
/* None */
profile
이런 미친 게임을 봤나! - 옥냥이

0개의 댓글