Post

[백준] 1509번: 팰린드롬 분할

[백준] 1509번: 팰린드롬 분할

📌 문제

https://www.acmicpc.net/problem/1509

📌 설명

처음부터 끝까지 문자열을 순회하면서 팰린드롬을 찾고, 계속하여 최솟값을 갱신해야 한다.

dp[i]를 i번 째 문자까지의 최소 분할 횟수라고 하자. 현재, 문자열의 i번 째 인덱스를 가리킨다고 할 때, i번 째 문자를 마지막으로 하는 팰린드롬이 있는지 확인한다. 만약 문자열 처음부터 팰린드롬이라면 최소 분할 횟수 minCuts를 1로 설정한다. 만약 j번 째 문자부터 i번 째 문자까지 팰린드롬이라면 분할 횟수는 dp[j - 1] + 1이다. 물론 이 경우가 최적이 아닐 수 있기 때문에 minCuts과 dp[j - 1] + 1 중 작은 값을 취해야 할 것이다.

📌 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <vector>
#include <string>

using namespace std;

string s;
int dp[2501]; // dp[i]: i번 째까지 분할된 팰린드롬의 최솟값

bool isPalindrome(int start, int end) {
    while (start < end) {
        if (s[start] != s[end]) {
            return false;
        }
        start++;
        end--;
    }
    return true;
}

int main() {
    cin >> s;
    
    int n = s.length();

    for (int i = 0; i < n; i++) {
        int minCuts = i + 1; // 최대 i + 1번 분할 가능
        for (int j = 0; j <= i; j++) {
            if (isPalindrome(j, i)) {
                // j부터 i까지 하나의 팰린드롬임. 이때 i까지 최소 팰린드롬의 수는 dp[j - 1] + 1이 될 수 있음.
                // 만약 처음부터 하나의 팰린드롬이라면 1로 간주
                minCuts = (j == 0) ? 1 : min(minCuts, dp[j - 1] + 1);
            }
        }
        dp[i] = minCuts;
    }

    cout << dp[n - 1];
}
This post is licensed under CC BY 4.0 by the author.