🧫 문제 분석
✔️ 출처
📖 문제

dp 문제
갈 수 없는 돌들이 있으므로 여러가지 경우의 수가 있기에 가장 먼저 출발한 것이 먼저 도착하는 것이 아니다.
각 돌에 도착할때 몇 점프로 도달했는지를 체크해줄 필요가 있다.
따라서 2차원 DP로 풀어야하는데 N*N 은 너무 커서 문제 조건에 맞지 않는다.
점프를 해도 결국 연속으로 누적된 x + 1이 가장 클 것이므로
연속으로 x + 1 이 누적되었을때 1만까지의 값은 142 정도이다.
넉넉하게 150으로 잡았다.
따라서 2차원 DP는 몇칸으로 현재 번호의 돌에 도착했는지 체크하면서 몇 번 점프했는지 값을 찾는다.
dp[현재 돌][몇 칸 점프해서 왔는지 점프 길이 : x]
탐색에는 BFS 탐색을 사용한다.
x-1, x, x+1 칸으로 점프하는 각각의 경우를 BFS로 탐색해주면된다.
그리고 생각을 잘못한게
입력 조건에서 1번과 N번은 충분히 크기가 크다고 했는데
이걸 제대로 안봐서 2번이 갈 수 없는 경우를 생각하지 못해서
96퍼에서 틀렸다.
급하게 풀면 안된다. 문제를 꼼꼼히 여러번 읽자
🔅 문제 풀이
import java.io.*;
import java.util.*;
public class Main {
static int N, M;
static int[][] dp;
static boolean[] smallRock;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
dp = new int[N + 1][150];
smallRock = new boolean[N + 1];
for (int i = 0; i < M; i++) {
int idx = Integer.parseInt(br.readLine());
smallRock[idx] = true;
}
if (smallRock[2]) {
System.out.println(-1);
return;
}
for (int i = 0; i <= N; i++) {
Arrays.fill(dp[i], -1);
}
bfs();
int answer = Integer.MAX_VALUE;
for (int i = 0; i < dp[N].length; i++) {
if (dp[N][i] == -1) continue;
answer = Math.min(answer, dp[N][i]);
}
System.out.println(answer == Integer.MAX_VALUE ? -1 : answer);
}
private static void bfs() {
Queue<int[]> q = new LinkedList<>();
q.add(new int[] {2, 1}); // 현재 돌 번호, 점프해온 거리 x
dp[2][1] = 1;
while (!q.isEmpty()) {
int[] cur = q.poll();
int curN = cur[0];
int x = cur[1];
if (curN == N) {
return;
}
int nextRock = curN + (x - 1);
if (x - 1 > 0 && nextRock <= N) {
if (dp[nextRock][x-1] == -1 && !smallRock[nextRock]) {
dp[nextRock][x-1] = dp[curN][x] + 1;
q.add(new int[]{nextRock, x - 1});
}
}
nextRock = curN + x;
if (nextRock <= N) {
if (dp[nextRock][x] == -1 && !smallRock[nextRock]) {
dp[nextRock][x] = dp[curN][x] + 1;
q.add(new int[]{nextRock, x});
}
}
nextRock = curN + x + 1;
if (nextRock <= N) {
if (dp[nextRock][x+1] == -1 && !smallRock[nextRock]) {
dp[nextRock][x+1] = dp[curN][x] + 1;
q.add(new int[]{nextRock, x + 1});
}
}
}
}
}
❗ 오답노트 / 필요한 지식
- 문제 잘 읽기
- 급하게 풀지 말
'baekjoon > DP' 카테고리의 다른 글
백준 1520번 : 내리막 길 [자바] (2) | 2025.08.29 |
---|---|
백준 14585번: 사수빈탕 [자바] (2) | 2025.07.10 |
백준 16565번 : N포커 [자바] (0) | 2025.07.01 |
백준 2533번 : 사회망 서비스 (SNS) [자바] (0) | 2025.06.27 |
백준 17626번 : Four Squaares [자바] (1) | 2025.06.13 |