Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- BFS
- DFS & BFS
- 백준 2261번
- 분할 정복(Divide and Conquer)
- 이분 그래프(Bipartite Graph)
- DFS
- 백준 1948번
- 플로이드 워셜 알고리즘(Floyd-Warshall Algorithm)
- 위상 정렬(Topology Sort)
- 백준 9012번
- BFS(Breadth First Search)
- 알고리즘 개념
- 위상 정렬(Topological Sort)
- 백준 2504번
- 동적 프로그래밍(Dynamic Programming)
- DFS(Depth First Search)
- 트리(Tree)
- 백준 1707번
- 그리디 알고리즘(Greedy Algorithm)
- 다익스트라 알고리즘(Dijkstra Algorithm)
- 스택(Stack)
- 백준 17608번
- 그래프(Graph)
- 백준 2493번
- 큐(Queue)
- 이분 탐색(Binary Search)
- 백준 10000번
- 백준 18352번
- 백준 2812번
- 백준 21606번
Archives
- Today
- Total
Always Be Wise
동적 프로그래밍 : 점프(백준 2253번) 본문
728x90
▶ 문제 : https://www.acmicpc.net/problem/2253
2253번: 점프
N(2 ≤ N ≤ 10,000)개의 돌들이 같은 간격으로 놓여 있다. 편의상 순서대로 1, 2, …, N번 돌이라고 부르자. 당신은 현재 1번 돌 위에 있는데, 이 돌들 사이에서 점프를 하면서 N번째 돌로 이동을 하려
www.acmicpc.net
##### 문제 #####
# N(2 ≤ N ≤ 10,000)개의 돌들이 같은 간격으로 놓여 있다.
# 편의상 순서대로 1, 2, …, N번 돌이라고 부르자.
# 당신은 현재 1번 돌 위에 있는데,
# 이 돌들 사이에서 점프를 하면서 N번째 돌로 이동을 하려 한다.
# 이때 다음 조건들이 만족되어야 한다.
# 이동은 앞으로만 할 수 있다.
# 즉, 돌 번호가 증가하는 순서대로만 할 수 있다.
# 제일 처음에 점프를 할 때에는 한 칸밖에 점프하지 못한다.
# 즉, 1번 돌에서 2번 돌이 있는 곳으로 점프할 수 있다.
# 그 다음부터는 가속/감속 점프를 할 수 있는데, 이전에 x칸 점프를 했다면,
# 다음번에는 속도를 줄여 x-1칸 점프하거나, x칸 점프하거나, 속도를 붙여 x+1칸 점프를 할 수 있다.
# 물론 점프를 할 때에는 한 칸 이상씩 해야 한다.
# 각 돌들은 각기 그 크기가 다르고,
# 그 중 몇 개의 돌은 크기가 너무 작기 때문에 당신은 그러한 돌에는 올라갈 수 없다.
# 위와 같은 조건들을 만족하면서 1번 돌에서 N번 돌까지 점프를 해 갈 때,
# 필요한 최소의 점프 횟수를 구하는 프로그램을 작성하시오.
##### 입력 #####
# 첫째 줄에 두 정수 N, M(0 ≤ M ≤ N-2)이 주어진다.
# M은 크기가 맞지 않는, 즉 크기가 작은 돌의 개수이다.
# 다음 M개의 줄에는 크기가 작은 돌들의 번호가 주어진다.
# 1번 돌과 N번 돌은 충분히 크기가 크다고 가정한다.
##### 출력 #####
# 첫째 줄에 필요한 최소의 점프 횟수를 출력한다.
# 만약 N번 돌까지 점프해갈 수 없는 경우에는 -1을 출력한다.
▶ 접근 방법
DP 테이블 구성이 굉장히 어려웠던 문제였다.
문제에서 주어진 정보를 테이블에 적용하는 연습이 많이 필요할 것 같다.
▶ 풀이 코드
import sys
# N : 최종 돌의 숫자, M : 착지할 수 없는 작은 돌의 갯수
N, M = map(int, sys.stdin.readline().split())
# DP 테이블(행은 단계별 돌의 숫자, 열은 속도)
# DP[i][j]의 의미는 i번째 돌에 j의 속도로 도착할 때의 점프 횟수
# 초깃 값은 'inf'로 설정한다.
# 최대 속도는 1부터 N까지 속도를 1씩 늘려간다고 했을 때의 근사 값이다.
DP = [[float('inf')] * (int((2 * N) ** 0.5) + 2) for _ in range(N + 1)]
DP[1][0] = 0
# 착지할 수 없는 돌들을 set에 넣어준다.
passing = set(int(sys.stdin.readline().rstrip()) for _ in range(M))
# 돌을 단계별로 하나씩 늘려간다.
for num_stone in range(2, N + 1):
# 도착하려고 하는 돌이 passing에 있으면 넘어간다.
if num_stone in passing:
continue
# 해당 돌에 도착할 수 있는 속도를 케이스별로 살펴본다.
for velocity in range(1, int((2 * num_stone) ** 0.5) + 1):
# DP[돌][속도]는 해당 돌에 도착하기 전 단계를 고려해야한다.
# 즉, 이전 단계의 속도보다 1 감속한 경우이거나, 이전 단계와 속도가 같은 경우이거나, 이전 단계보다 속도를 1 가속한 경우이다.
DP[num_stone][velocity] = min(DP[num_stone-velocity][velocity-1], DP[num_stone-velocity][velocity], DP[num_stone-velocity][velocity+1]) + 1
if min(DP[N]) == float('inf'):
print(-1)
else:
print(min(DP[N]))
▶ 관련 링크
2021.11.25 - [알고리즘] - 동적 프로그래밍(Dynamic Programming)이란?
2021.11.25 - [알고리즘] - 동적 프로그래밍 : 피보나치 수 2(백준 2748번)
2021.11.25 - [알고리즘] - 동적 프로그래밍 : 01타일(백준 1904번)
2021.11.26 - [알고리즘] - 동적 프로그래밍 : 평범한 배낭(백준 12865번)
2021.11.27 - [알고리즘] - 동적 프로그래밍 : 동전(백준 9084번)
'알고리즘 > 백준' 카테고리의 다른 글
동적 프로그래밍 : 계단 오르기(백준 2579번) (0) | 2021.12.01 |
---|---|
동적 프로그래밍 : 연속합(백준 1912번) (0) | 2021.11.30 |
그리디 알고리즘 : 멀티탭 스케줄링(백준 1700번) (0) | 2021.11.27 |
그리디 알고리즘 : 신입사원(백준 1946번) (0) | 2021.11.27 |
그리디 알고리즘 : 회의실 배정(백준 1931번) (0) | 2021.11.27 |
Comments