[BaekJoon 1463 : 동적계획법, Python] - 1로 만들기
2021, Oct 28
백준 1463 1로 만들기 : 실버 3
Solution
1. DP Memoization 활용(Bottom-up)
- DP[k] 는 어차피 ‘상태’ 에 대한 값이기 때문에 과정 상관 없이 가능한 경우를 모두 고려해 그 중 최소값만 저장하면 된다.
import sys
input = sys.stdin.readline
n = int(input())
DP = [-1 for _ in range(n+1)]
for i in range(1, n+1):
cnt = float('inf')
if i%3 == 0:
cnt = min(cnt, DP[i//3] + 1)
if i%2 == 0:
cnt = min(cnt, DP[i//2] + 1)
cnt = min(cnt, DP[i-1] + 1)
DP[i] = cnt
print(DP[n])
2. BFS - deque 사용
- popleft 과정에서 재정렬에 시간이 소요돼 시간초과가 나오는 거 같다.
import sys
from collections import deque
input = sys.stdin.readline
n = int(input())
tmps = deque([[n, 0]])
while tmps:
cur_num, cur_cnt = tmps.popleft()
if cur_num == 1:
print(cur_cnt)
sys.exit(0)
nxt_cnt = cur_cnt + 1
if cur_num%3 == 0:
tmp3 = cur_num/3
if tmp3 == 1:
print(nxt_cnt)
sys.exit(0)
tmps.append([tmp3, nxt_cnt])
if cur_num%2 == 0:
tmp2 = cur_num/2
if tmp2 == 1:
print(nxt_cnt)
sys.exit(0)
tmps.append([tmp2, nxt_cnt])
tmp1 = cur_num-1
if tmp1 == 1:
print(nxt_cnt)
sys.exit(0)
tmps.append([tmp1, nxt_cnt])
풀이과정 및 느낀점
위 두 개의 풀이 외에 bfs 로 풀면서, 우선 3으로 나눠지면 3으로만 나누고 나머지 값들은 굳이 deque 에 저장하지 않는 방법을 사용해봤다.
시간초과는 해결되었지만 80%까지 정도 갔을 때 ‘틀렸습니다’ 가 나왔다. (뭐지..?)
반례를 찾아보려 했는데, 반례는 모르겠고 cnt 수가 똑같은 경우는 6의 배수인 경우에서 매번 나왔다. (당연하게도..)