[BOJ] 1695 : 팰린드롬 만들기(Java)

문제

앞에서 뒤로 보나, 뒤에서 앞으로 보나 같은 수열을 팰린드롬 이라고 한다. 예를 들어 {1}, {1, 2, 1}, {1, 2, 2, 1}과 같은 수열은 팰린드롬 이지만, {1, 2, 3}, {1, 2, 3, 2} 등은 팰린드롬이 아니다.

한 수열이 주어졌을 때, 이 수열에 최소 개수의 수를 끼워 넣어 팰린드롬을 만들려고 한다. 최소 몇 개의 수를 끼워 넣으면 되는지를 알아내는 프로그램을 작성하시오.

입력

첫째 줄에 수열의 길이 N(1≤N≤5,000)이 주어진다. 다음 줄에는 N개의 수열을 이루는 수들이 주어진다. 각 수들은 int 범위이다.

출력

첫째 줄에 끼워 넣을 수들의 최소 개수를 출력한다.

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


💡 풀이

앞, 뒤로 보았을 때 숫자가 같아야하기 때문에 두 포인터(Two Pointer)를 사용했다.

앞의 시작을 L, 뒤의 시작을 R이라 두고 시작한다. 이때 시작의 L, R은 각각 0, N-1이 된다. 

만약 주어진 숫자의 L 번째, R 번째 숫자가 같다면, L+1, R-1을 통해 한 자리 씩 줄여 나아간다. 만약 이 두 숫자가 다를 경우, 숫자를 끼워 넣어 추가해야 한다. 이때 L을 1 증가시키는 방법과 R을 1 감소 시키는 방법, 이 두 가지의 경우가 존재한다. 
재귀를 통해 이 둘 중 끼워 넣을 수가 최소인 값을 반환하도록 한다. 여기서 다이나믹 프로그래밍을 사용하여, L ~ R의 범위에서 끼워 넣을 수가 최소인 것의 개수를 저장하여 반환하도록 했다. 

 

전체적인 코드는 다음과 같다. 

import java.util.Arrays;
import java.util.Scanner;

public class Q1695 {
    static int N;
    static int[] numbers;
    static int[][] dp;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        N = sc.nextInt();

        numbers = new int[N];
        for (int i = 0; i < N; i++) {
            numbers[i] = sc.nextInt();
        }

        dp = new int[N][N];
        for (int[] ints : dp) {
            // dp의 초기값을 -1로 저장
            Arrays.fill(ints, -1);
        }

        int L = 0;
        int R = N - 1;
        System.out.println(recur(L, R));
    }

    static int recur(int L, int R) {
        // 기저 사례 : L이 R보다 크면 종료 
        if (L > R) {
            return 0;
        }

        // dp[L][R]에 값이 저장되어 있다면, 바로 반환하고 종료
        if (dp[L][R] != -1) {
            return dp[L][R];
        }

        if (numbers[L] == numbers[R]) {
            dp[L][R] = recur(L + 1, R - 1);
        } else {
            dp[L][R] = Math.min(recur(L + 1, R) + 1, recur(L, R - 1) + 1);
        }

        return dp[L][R];
    }
}

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

[BOJ] 1005 : ACM Craft(Java)  (0) 2023.05.03
[BOJ] 10942 : 팰린드롬?(Java)  (0) 2023.05.03
[BOJ] 1766 : 문제집(Java)  (0) 2023.04.16
[BOJ] 2252 : 줄 세우기(Java)  (0) 2023.04.14
[BOJ] 15681 : 트리와 쿼리(Java)  (0) 2023.04.14