1695번: 팰린드롬 만들기
앞에서 뒤로 보나, 뒤에서 앞으로 보나 같은 수열을 팰린드롬 이라고 한다. 예를 들어 {1}, {1, 2, 1}, {1, 2, 2, 1}과 같은 수열은 팰린드롬 이지만, {1, 2, 3}, {1, 2, 3, 2} 등은 팰린드롬이 아니다. 한 수열
www.acmicpc.net
1. 문제 요약
- 제한시간 2초
- 수열을 입력받고, 최소 몇 개의 숫자를 입력받으면 팰린드롬이 되는지 알아내는 문제
2. 아이디어 (문제 접근법)
[아이디어-1]
- 참조 링크의 풀이를 태블릿 그림으로 이해하며 풀어보았다
- 입력받은 수열을 기록하기 위해 int[] arr = new int[N] 생성
- 다른 DP 문제들과 마찬가지로 연산 결과를 배열에 담기 위해 int[][] DPArr = new int[N][N] 를 생성
- 이후 DPArr 의 값들을 -1로 초기화한다
- arr 의 왼쪽과 오른쪽 투 포인터 역할을 할 int left 와 int right 를 파라미터로 갖는
DP(int left, int right) -> DP(0, N-1) 실행
다음 포인터란 left+1 과 right-1을 의미한다 (가운데로 범위를 좁혀감)
- if (left >= right) return 0;
투 포인터가 교차하면
- 0 반환
- if (DPArr[left][right] != -1) return DPArr[left][right];
이미 해당 위치까지의 최소값을 구했으면
- 해당 값 반환
- if (arr[left] == arr[right])
각 포인터가 가리키는 값이 같으면
- DPArr[left][right] = DP(left+1, right-1);
- return DP(left+1, right-1);
다음 포인터가 가리키는 값을 기록하고 반환 (추가한 게 없기 때문)
- else
각 포인터가 가리키는 값이 다르면
- DPArr[left][right] = Math.min(DP(left+1 ,right)+1, DP(left ,right-1)+1);
- return Math.min(DP(left+1 ,right)+1, DP(left ,right-1)+1);
왼쪽이나 오른쪽 포인터 중 하나만 다음 위치로 이동
이후 해당 위치의 DP 값중 더 작은 값 + 1 을 기록하고 반환 (숫자 하나를 추가하기 때문)
3. 어려움 및 해결
- 수열이 주어졌을 때 왼쪽, 오른쪽 끝 각각에 left, right 포인터를 만든다
- 이후 가운데로 하나씩 좁혀오며 포인터가 가리키는 값이 다른 경우
- 왼쪽에 오른쪽 값 생성
- 오른쪽에 왼쪽 값 생성
의 두 가지 경우의 수 발생
- 이것만으로는 메모이제이션은 가능하지만 최소의 개수가 나오는 경우의 수를 구하지 못한다
- 아이디어가 나오지 않아 다른 사람의 풀이를 참조
[백준]1695번 팰린드롬 만들기 2️⃣
\[백준]1695번 팰린드롬 만들기이전에 풀었던 문제인데 당시에 풀지 못해서 다른 사람 풀이를 봤었다. 다시 풀어보았다. 내 머리속에 항상 먼저 드는 생각은 투포인터이다....;.1\. left, right라는 두
velog.io
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class BOJ_1695_팰린드롬_만들기 {
static int N;
static int[] arr;
static int[][] DPArr;
static int DP(int left, int right){
if(left >= right) return 0;
if(DPArr[left][right] != -1) return DPArr[left][right];
if(arr[left]==arr[right]){
int min = DP(left+1, right-1);
DPArr[left][right] = min;
return min;
}else{
int min = Math.min(DP(left+1 ,right)+1, DP(left ,right-1)+1);
DPArr[left][right] = min;
return min;
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer stk;
N = Integer.parseInt(br.readLine());
arr = new int[N];
DPArr = new int[N][N];
stk = new StringTokenizer(br.readLine());
for(int i=0; i<N; i++) {
arr[i] = Integer.parseInt(stk.nextToken());
Arrays.fill(DPArr[i], -1);
}
System.out.println(DP(0, N-1));
}
}
'[Solved] > BOJ' 카테고리의 다른 글
[백준12865] 평범한 배낭 (0) | 2023.05.25 |
---|---|
[백준 5557] 1학년 (0) | 2023.05.24 |
[백준 11055] 가장 큰 증가하는 부분수열 (0) | 2023.05.20 |
[백준 2839] 설탕 배달 (0) | 2023.05.18 |
[백준 1106] 호텔 (0) | 2023.05.17 |