https://www.acmicpc.net/problem/13549
13549번: 숨바꼭질 3
수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일
www.acmicpc.net
1. BFS문제인데 DP로 생각했다.
2. 우선순위큐를 활용한 BFS라 신기했다.
처음 풀때
이런식으로 하나씩 쓰다보면서 규칙을 발견해보려고 했다.
짝수인경우) X_i = min( X_i/2 , X_i-1 + 1)
홀수인경우) X_i = X_i-1 + 1
이라는 점화식을 세웠다.
subin, target = map(int, input().split())
d = [-1] * 100002
d[subin] = 0
d[subin+1] = 1
for i in range(subin+2, target+1) :
if i%2 == 0 and d[i//2] != -1:
d[i] = min(d[i//2], d[i-1]+1)
else :
d[i] = d[i-1] + 1
print(d[target])
근데

하하하!
로그 찍어보니까

이렇게 나왔다. 최적값을 제대로 못 구하고 있음을 알 수 있다.
두배수로 점프하는게 가장 적은 값인데, 이걸 한번 배열 전체에 기록을 하고, 또 이걸기반으로 또 배열 전체를 기록을 하는 식으로 진행해야 최적값을 제대로 구할 수 있음을 알게 됐다. (나는 배열 전체를 한번만 검색하는 식으로 만들어서,, 최적값이 나올 수 가 없었다.)
그래서 검색하니까 DP가 아니라 BFS 더라 .. ^^
오해해서 미안했다..

이렇게 우선순위 큐를 돌리면 빠르게 최적값을 찾아낼 수 있다!!
이런식의 우선순위큐를 활용한 BFS도 있군아 재밌다
최종 코드
from collections import deque
def bfs() :
graph = [-1] * 100001
graph[subin] = 0
que = deque([subin])
while que :
target = que.popleft()
# 동생 위치에 도달시(정답발견)
if target == sister :
return graph[target]
for i in (target+1, target-1, target*2) : # 세가지 방법을 순서대로 진행
# 이동하는 곳이 범위내이며 / 한번도 방문하지 않았으면
if 0<=i<=100000 and graph[i] == -1 :
# 순간이동인경우
if i == target*2 :
graph[i] = graph[target]
que.appendleft(i) # 순간이동이니까 먼저 탐색
else :
graph[i] = graph[target] + 1
que.append(i)
subin, sister = map(int, input().split())
print(bfs())

굿!
'알고리즘 풀이' 카테고리의 다른 글
| [#2667 : 파이썬] 단지번호붙이기 - BFS (0) | 2022.11.23 |
|---|---|
| [#1010] 다리놓기 (1) | 2022.11.22 |
| [#1316] 그룹단어 체커 (0) | 2022.11.21 |
| [#2217] 로프 (0) | 2022.11.18 |
| [#20436] ZOAC3 (0) | 2022.11.17 |


