[백준] 1695번 - 팰린드롬 만들기 (Gold 4)
업데이트:
문제 링크
문제 설명
앞에서부터 뒤로 보나, 뒤에서부터 앞으로 보나 같은 수열을 팰린드롬이라고 한다.
수열이 주어졌을 때, 이 수열에 가장 적은 개수의 수들을 끼워넣어 팰린드롬으로 만드려고 한다.
필요한 최소의 수를 구하시오.
정답 코드 및 설명
DP를 사용하여 풀이한다.
원래 수열 arr의 i번째 원소부터 j번째 원소까지로 이루어진 부분 수열을 생각하자.
이 부분 수열을 팰린드롬으로 만들기 위한 수들의 최소의 개수를 makePalindrom[i][j]라고 하자.
길이가 1인 부분수열은 이미 팰린드롬이므로, 수를 더 추가할 필요가 없다.
첫 원소가 (i-length)번째 원소이고 마지막 원소가 (i - 1)번째 원소인 길이가 length인 부분수열을 생각하자.
크게 세 가지 경우로 나누어진다.
- 첫 원소 arr[i - length]과 마지막 원소 arr[i - 1]이 다른 경우
- 최소의 개수의 수를 추가해서 팰린드롬을 만드는 방법에는 두 가지 후보가 있다.
- 맨 앞에 arr[i - 1]을 추가하는 경우 : makePalindrom[i - length][i - 2] + 1
- 마지막에 arr[i - length]를 추가하는 경우 : makePalindrom[i - length + 1][i - 1] + 1
- 둘 중 작은 값이 makePalindrom[i - length][i - 1]이 된다.
- 길이가 2보다 크고, 첫 원소 arr[i - length]와 마지막 원소 arr[i - 1]이 같은 경우
- 첫 원소와 마지막 원소를 빼고 생각해도 동일하다.
- makePalindrom[i - length][i - 1] = makePalindrom[i - length + 1][i - 2]
- 길이가 2이면서 첫 원소 arr[i - length]와 마지막 원소 arr[i - 1]이 같은 경우
- 이미 팰린드롬이므로 makePalindrom[i - length][i - 1] = 0
이를 코드로 구현하면 아래와 같다.
배열의 크기가 $N^2$이고 각각의 값을 구하는데는 상수시간이 들어가므로, 전체 시간 복잡도는 $O(N^2)$이다.
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
40
41
42
43
44
45
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class BOJ1695 {
int[] arr;
void input() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
StringTokenizer st = new StringTokenizer(br.readLine());
arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = Integer.parseInt(st.nextToken());
}
}
int dp() {
// makePalindrom[i][j] : arr[i]~arr[j] 부분수열에 대한 답
int[][] makePalindrom = new int[arr.length][arr.length];
for (int length = 2; length <= arr.length; length++) {
for (int i = length; i <= arr.length; i++) {
if (length > 2 && arr[i - length] == arr[i - 1]) {
makePalindrom[i - length][i - 1] = makePalindrom[i - length + 1][i - 2];
}
if (arr[i - length] != arr[i - 1]) {
makePalindrom[i - length][i - 1] = Math.min(makePalindrom[i - length][i - 2],
makePalindrom[i - length + 1][i - 1]) + 1;
}
}
}
return makePalindrom[0][arr.length - 1];
}
void solution() throws IOException {
input();
System.out.println(dp());
}
public static void main(String[] args) throws IOException {
new BOJ1695().solution();
}
}
댓글남기기