알고리즘 유형 : DP(Dynamic Programming)
풀이 참고 없이 스스로 풀었나요? : △
https://www.acmicpc.net/problem/12852
import sys
input = sys.stdin.readline
N = int(input())
mem = [0]*(N+1) # 연산 횟수 메모이제이션
path = ["" for _ in range(N+1)] # 최단 경로
path[1] = "1"
for idx in range(2, N+1):
mem[idx] = mem[idx-1] + 1
prev = idx-1
if idx % 3 == 0 and mem[idx//3]+1 < mem[idx]:
mem[idx] = mem[idx//3] + 1
prev = idx // 3
if idx % 2 == 0 and mem[idx//2]+1 < mem[idx]:
mem[idx] = mem[idx//2] + 1
prev = idx // 2
path[idx] = str(idx) + " " + path[prev]
print(mem[N])
print(path[N])
풀이 요약
먼저 전체 문제를 부분 문제에 관한 점화식으로 세워보자.
count(N) = min(count(N//3), count(N//2), count(N-1)) + 1로 정의할 수 있다.
count(1) = 0이므로 초기화해주고, 2부터 N까지 순회하면서 메모이제이션 리스트를 활용하여 바텀업 방식으로 쭉 구해나가면 된다.
이 때, prev 변수에 실제로 갱신에 사용된 이전의 수의 path index를 저장해준다.
그 후, -1, x2, x3 조건문을 모두 거친 후 prev에는 최종적으로 갱신에 사용된 부분 문제 숫자가 담겨있으므로, path[prev]와 현재 숫자를 합하여 path[idx]를 갱신해준다.
배운 점, 어려웠던 점