본문 바로가기

정글캠프-WIL/알고리즘

점프 (DP)

문제

N(2 ≤ N ≤ 10,000)개의 돌들이 같은 간격으로 놓여 있다. 편의상 순서대로 1, 2, …, N번 돌이라고 부르자. 당신은 현재 1번 돌 위에 있는데, 이 돌들 사이에서 점프를 하면서 N번째 돌로 이동을 하려 한다. 이때 다음 조건들이 만족되어야 한다.

  1. 이동은 앞으로만 할 수 있다. 즉, 돌 번호가 증가하는 순서대로만 할 수 있다.
  2. 제일 처음에 점프를 할 때에는 한 칸밖에 점프하지 못한다. 즉, 1번 돌에서 2번 돌이 있는 곳으로 점프할 수 있다. 그 다음부터는 가속/감속 점프를 할 수 있는데, 이전에 x칸 점프를 했다면, 다음번에는 속도를 줄여 x-1칸 점프하거나, x칸 점프하거나, 속도를 붙여 x+1칸 점프를 할 수 있다. 물론 점프를 할 때에는 한 칸 이상씩 해야 한다.
  3. 각 돌들은 각기 그 크기가 다르고, 그 중 몇 개의 돌은 크기가 너무 작기 때문에 당신은 그러한 돌에는 올라갈 수 없다.

위와 같은 조건들을 만족하면서 1번 돌에서 N번 돌까지 점프를 해 갈 때, 필요한 최소의 점프 횟수를 구하는 프로그램을 작성하시오.

 

입력

첫째 줄에 두 정수 N, M(0 ≤ M ≤ N-2)이 주어진다. M은 크기가 맞지 않는, 즉 크기가 작은 돌의 개수이다. 다음 M개의 줄에는 크기가 작은 돌들의 번호가 주어진다. 1번 돌과 N번 돌은 충분히 크기가 크다고 가정한다.

 

출력

첫째 줄에 필요한 최소의 점프 횟수를 출력한다. 만약 N번 돌까지 점프해갈 수 없는 경우에는 -1을 출력한다.

 

예제 입력 1

19 3
11
6
16

예제 출력 1

6

 

- 문제 해결

처음엔 이 문제를 dfs로 풀어보려고 했다. (visited를 set으로 두고, (이동 위치, 속도)를 담았음)

하지만 이 방식이 잘 못 된 접근 방식이라는 것을 깨닫는데는 오래지 않았다.

그 이유가 visited가 막히는 부분이 존재하는데 그쪽으로 가는 길이 더 빠를 수도 있기 때문이다.

(전체 탐색을 하지 않고 visited로 관리를 하려고 하다가 생기는 문제였다.) 결국 전체탐색을 하면 시간복잡도가 상당히 커지므로 결국에는 점화식을 정리하고자 한다. (아무리 생각해봐도 이건 아직까지는 생각 못할 것 같다..)

INF = float('inf')

for i in range(2, n + 1):
    if i in blocked:
        continue
    for j in range(1, max_jump + 1):
        prev = i - j
        if prev < 1:
            continue

        dp[i][j] = min(
            dp[prev][j - 1] if j - 1 >= 0 else INF,
            dp[prev][j],
            dp[prev][j + 1] if j + 1 <= max_jump else INF
        ) + 1

 

'정글캠프-WIL > 알고리즘' 카테고리의 다른 글

Malloc 구현 - C언어  (0) 2026.04.17
동전 (DP)  (0) 2026.04.02
LCS (DP) - Longest Common Subsequence  (0) 2026.04.02
평범한 배낭 (DP)  (0) 2026.04.02
동전 2 (BFS)  (0) 2026.03.26