[Dynamic Programming] 1로 만들기

Update:     Updated:

카테고리:

태그:

1로 만들기

난이도 : ⭐⭐

정수 X가 주어질 때 정수 X에 사용할 수 있는 연산은 다음과 같이 4가지이다.

  • X가 5로 나누어떨어지면, 5로 나눈다.
  • X가 3으로 나누어떨어지면, 3으로 나눈다.
  • X가 2로 나누어떨어지면, 2로 나눈다.
  • X에서 1을 뺀다.

정수 X가 주어졌을 때, 연산 4개를 적절히 사용해서 1을 만들려고 한다. 연산을 사용하는 횟수의 최솟값을 출력하시오.

예를 들어 정수가 26이면 다음과 같이 계산해서 3번의 연산이 최솟값이다.

    1. 26 - 1 = 25
    1. 25 / 5 = 5
    1. 5 / 5 == 1

입력 조건

  • 첫째 줄에 정수 X가 주어진다. (1 <= X <= 30,000)

출력 조건
첫째 줄에 연산을 하는 횟수의 최솟값을 출력한다.

입력 예시
26

출력 예시
3

나의 풀이

틀려서 추후에 추가 예정

문제 해설

이 문제는 잘 알려진 다이나믹 프로그래밍이라고 한다. 나는 왜 몰랐지..? 문제를 풀기 전에 함수가 호출되는 과정을 그려보면 이해하는 데 도움이 된다.
예를 들어 X = 6일 때, 함수가 호출되는 과정을 그리면 다음과 같다. 확인해보면 f(2)와 같은 함수들이 동일하게 여러 번 호출되는 것을 알 수 있다.

image

이제 문제에서 요구하는 내용을 점화식으로 표현하면 아래와 같다. 점화식 끝에 1을 더해주는 이유는 함수의 호출 횟수를 구해야 하기 때문이다.

image

실제 코드로 구현할 때는 1을 빼는 연산을 제외하고는 해당 수로 나누어떨어질 때에 한해서만 점화식을 적용할 수 있다.

답안 예시

# 정수 X를 입력받기
x = int(input())

# 앞서 계산된 결과를 저장하기 위해 DP 테이블 초기화
d = [0] * 30001

# 다이나믹 프로그래밍 진행(보텀업)
for i in range(2, x + 1):
    # 현재의 수에서 1을 빼는 경우
    d[i] = d[i - 1] + 1
    # 현재의 수가 2로 나누어 떨어지는 경우
    if i % 2 == 0:
        d[i] = min(d[i], d[i // 2] + 1)
    # 현재의 수가 3으로 나누어 덜어지는 경우
    if i % 3 == 0:
        d[i] = min(d[i], d[i // 3] + 1)
    # 현재의 수가 5로 나누어 떨어지는 경우
    if i % 5 == 0:
        d[i] = min(d[i], d[i // 5] + 1)

print(d[x])

🐢 현재 공부하고 있는 이것이 취업을 위한 코딩 테스트다 with 파이썬 - 나동빈 저자 의 책을 학습하며 기록 및 정리를 하기위한 내용들입니다. 🐢

감사합니다.😊

Algorithm 카테고리 내 다른 글 보러가기

댓글남기기