just inside

[백준] Silver 3. 1463 - 1로 만들기 python 본문

coding test/dp

[백준] Silver 3. 1463 - 1로 만들기 python

방울도마도 2024. 8. 9. 10:22
728x90

문제 링크

https://www.acmicpc.net/problem/1463


문제 설명

정수 X에 사용할 수 있는 연산은 다음과 같이 세 가지 이다.

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

정수 N이 주어졌을 때, 위와 같은 연산 세 개를 적절히 사용해서 1을 만들려고 한다. 연산을 사용하는 횟수의 최솟값을 출력하시오.

 

입력

첫째 줄에 1보다 크거나 같고, 106보다 작거나 같은 정수 N이 주어진다.

 

출력

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


제출 코드

  • 이번에 제출한 코드
import sys

input = sys.stdin.readline

n = int(input().rstrip())
dp = [0 for _ in range(n+1)]

if n == 1:
    print(0)
elif n == 2 or n == 3:
    print(1)
else:
    dp[2], dp[3] = 1, 1
    for i in range(4,n+1):
        if i % 3 == 0 and i % 2 == 0:
            dp[i] = min(dp[i//3], dp[i//2], dp[i-1]) + 1
        elif i % 3 == 0:
            dp[i] = min(dp[i//3], dp[i-1]) + 1
        elif i % 2 == 0:
            dp[i] = min(dp[i//2], dp[i-1]) + 1
        else:
            dp[i] = dp[i-1] + 1
    
    print(dp[n])
  • 비효율적이라고 생각해서 확인한 2년 전 풀었던 코드.
import sys
input = sys.stdin.readline

n = int(input())
d = [0] * (n+1)

for i in range(2, n+1):
    d[i] = d[i-1] + 1
    if i % 3 == 0:
        d[i] = min(d[i//3] + 1, d[i])
    if i % 2 == 0:
        d[i] = min(d[i//2] + 1, d[i])

print(d[n])

 

풀이

  • 다이나믹 프로그래밍 방법을 통해 풀이한다.
  • 3가지 연산이 있으므로, 일단 1을 뺀 값을 현재 위치에 저장한다.
    • i가 3으로 나누어 떨어지면, 현재 값과 3으로 나누어 떨어진 값 + 1을 비교하여 더 작은 값으로 업데이트
    • i가 2로 나누어 떨어지면, 현재 값과 2로 나누어 떨어진 값 + 1을 비교하여 더 작은 값으로 업데이트
  • 예전에 풀었던 코드는 점화식을 그렇게 찾아서 확인했다.
  • 이번에 푼 코드는 보다 케이스를 구체적으로 따져서 확인했는데, 코드가 너무 길어져서 함께 정리해 보았다.

 

알아둘 사항

2024.07.16 - [coding test/알고리즘] - 다이나믹 프로그래밍 (Dynamic Programming, DP)

 

다이나믹 프로그래밍 (Dynamic Programming, DP)

복잡한 문제를 해결하기 위해 사용되는 최적화 기법큰 문제를 여러 작은 부분 문제로 나누어 해결하고, 그 결과를 저장하여 같은 부분 문제를 반복적으로 해결하지 않도록 하는 방식최적화 문

me-unknown.tistory.com

 

728x90