본문 바로가기
Algorithm/이것이 코딩테스트다

[Python][이코테] 1로 만들기 / DP

by 애기 개발자 2022. 10. 23.
반응형

문제 설명

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

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

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

 

예를 들어 정수가 26이면

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

입력 조건

  • 첫째 줄에 정수 x가 주어진다. (1 ≤ x ≤ 30,000)

출력 조건

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

 

입력 예시

26

출력 예시

3

솔직히 어떻게 풀어야 할지 감도 안 잡혀서 걍 풀이를 보고

 

풀이를 보고도 뭐지.. 싶어서 하나하나 돌려봤다.

 

# 8-5 DP 1로 만들기
x = int(input())

# DP 테이블 초기화
d = [0] * 30001

#Bottom-Up
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])

이를 파이썬 튜터에서 실행시켜 보았다.

 

https://pythontutor.com/

 

Python Tutor: Learn Python, JavaScript, C, C++, and Java programming by visualizing code

Learn Python, JavaScript, C, C++, and Java This tool helps you learn Python, JavaScript, C, C++, and Java programming by visualizing code execution. You can use it to debug your homework assignments and as a supplement to online coding tutorials. Related s

pythontutor.com

 

for i in range(2, x+1):

반복문이 2부터 시작하는 이유는

 

먼저 [0]으로 초기화 시켜 주었고, x가 1인 경우에는 답이 그대로 1이기 때문에 

 

[0] + 1 을 해서 출력하면 그대로 정답이기에 2부터 시작한다.

 

i = 2일땐 

 

d[i] = d[i-1] + 1 #d[2] = d[2-1] + 1 -> 0 + 1 = 1

if i % 2 == 0:
        d[i] = min(d[i], d[i//2] + 1) # d[2] = 1, d[2//2] + 1 = 0 + 1 -> 1

i = 3일땐

d[i] = d[i-1] + 1 # d[3] = d[2] + 1 -> 1 + 1 = 2

if i % 3 == 0:
        d[i] = min(d[i], d[i//3] + 1)
        #d[3] = min(d[3], d[1] + 1) -> min(2, 0+1=2) -> 1

 

쭉 반복하여

 

i = 25일 때

 

i = 24 일때 까지의 DP 테이블

d[i] = d[i-1] + 1 # d[25] = d[24] + 1 -> d[24]=4 -> d[25] = 4 + 1 = 5

if i % 5 == 0:
        d[i] = min(d[i], d[i // 5] + 1)
        #d[25] = min(d[25], d[25 // 5] + 1) -> d[5] = 1 -> d[5] + 1 = 1 + 1 = 2
        #d[25] = min(5, 2) -> d[25] = 2

 

i = 26 일 때

d[i] = d[i-1] + 1 # d[26] = d[26-1] + 1 -> d[25] + 1 = 2 + 1 = 3

if i % 2 == 0:
        d[i] = min(d[i], d[i//2] + 1)
        #d[26] = min(d[26], d[26//2] + 1) -> min(d[26], d[13] + 1)
        #d[26] = 3, d[13] = 4 -> min(3, 4+1) -> 3

 

위와 같은 방법으로 실행된다.

 

즉 2~26 (입력된 x값)까지 모든 계산 방법 중 가장 최소의 계산 횟수를 계속해서 비교해가며

 

DP테이블에 가장 최소한의 계산방법을 저장해 가는 것이다.

 

직접 해보면서 값을 하나하나 확인해 보는 게 이해하는데 가장 빠를 것이다.

반응형

댓글