수학과의 좌충우돌 프로그래밍

[C++] BAEKJOON 1509 팰린드롬 분할 본문

알고리즘/C++

[C++] BAEKJOON 1509 팰린드롬 분할

ssung.k 2019. 9. 6. 17:31

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

 

1509번: 팰린드롬 분할

세준이는 어떤 문자열을 팰린드롬으로 분할하려고 한다. 예를 들어, ABACABA를 팰린드롬으로 분할하면, {A, B, A, C, A, B, A}, {A, BACAB, A}, {ABA, C, ABA}, {ABACABA}등이 있다. 분할의 개수의 최솟값을 출력하는 프로그램을 작성하시오.

www.acmicpc.net

 

지난 포스팅에서는 팰린드롬인지 아닌지 판별하는 문제를 동적계획법을 이용해서 해결해보았습니다.

팰린드롬?

 

[C++] BAEKJOON 10942 팰린드롬?

https://www.acmicpc.net/problem/10942 10942번: 팰린드롬? 총 M개의 줄에 걸쳐 홍준이의 질문에 대한 명우의 답을 입력으로 주어진 순서에 따라서 출력한다. 팰린드롬인 경우에는 1, 아닌 경우에는 0을 출력한다..

ssungkang.tistory.com

이번 문제는 이를 응용하여 해결할 수 있습니다. 동적계획법을 통해 dp[i]][j] (=i번째부터 j번째 까지의 문자열이 팰린드롬인지) 를 정의하고 이를 통해 문제를 해결합니다. count[i] ( i 번째 까지 문자열에 대해 팰린드롬 분할의 개수의 최솟값) 에 값을 저장합니다. i 를 기준으로 j 를 1부터 i 까지 순회하며 j~i 의 문자열이 팰린드롬을 이룬다면 이것으로 자르는게 최소 분할이 될지를 검사해줍니다. 그러기 위해 count 배열에는 큰 수로 초기화 시켜놨습니다.

#include <iostream>
#include <string>

using namespace std;

bool dp[2501][2501];

int main() {
    
    int count[2501];
    
    string s;
    cin >> s;
    int n = s.size();
    s = " " + s;
    
    for (int i=1; i<=n; i++) {
        dp[i][i] = true;
    }
    for (int i=1; i<=n-1; i++) {
        if (s[i] == s[i+1]) {
            dp[i][i+1] = true;
        }
    }
    for (int k=2; k<n; k++) {
        for (int i=1; i<=n-k; i++) {
            int j = i+k;
            if (s[i] == s[j] && dp[i+1][j-1]){
                dp[i][j] = 1;
            }
        }
    }
    count[0] = 0;
    for (int i=1; i<=n; i++) {
        count[i] = 987654321;
        for (int j=1; j<=i; j++) {
            if (dp[j][i]) {
                if (count[i] > count[j-1]+1) {
                    count[i] = count[j-1]+1;
                }
            }
        }
    }

    cout << count[n] << '\n';
    return 0;
}

 

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

[C++] BAEKJOON 2293 동전 1  (0) 2019.09.06
[C++] BAEKJOON 2156 포도주 시식  (0) 2019.09.06
[C++] BAEKJOON 10942 팰린드롬?  (0) 2019.09.06
[C++] BAEKJOON 1890번 점프  (0) 2019.09.06
[C++] BAEKJOON 5052번 전화번호목록  (0) 2019.08.26
Comments