알고리즘 스터디 [DP] - 백준 1463번(feat. Python)

김진성·2021년 10월 27일
1

Algorithm 문제풀이

목록 보기
1/63

동적계획법 개념을 익히고 난 후 처음으로 풀어보는 문제 : 백준 1463 (feat. Python)

백준 1463 : 1로 만들기

문제

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

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

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

나만의 문제 해석

일단, 동적 계획법은 모든 경우의 수에 대해서 알아보고 그 중 최적의 경로를 찾는 것이다. 이를 적용해보자.

  1. 횟수를 적게 하는 방법은 큰 수로 바로 나누어지는 것이다.
  2. 3으로 나누어지지 않으면 2로 나누어서 해보기
  3. 3으로 나누었을 때 몫이 1이면 빼기를 해보는 것이 2로 나누는 것보다 앞선다.
  4. 3과 2로도 나누어지지 않으면 1을 빼보자.

입력에 대한 출력을 한번 나열해보자.

  • solution(2) = 1
  • solution(3) = 1
  • solution(4) = 4 -> 2 -> 1 = 2
  • solution(5) = 5 -> 4 -> 2 -> 1 = 3
  • solution(6) = 6 -> 2 -> 1 = 2
  • solution(7) = 7 -> 6 -> 2 -> 1 = 3
  • solution(8) = 8 -> 4 -> 2 -> 1 = 3
  • solution(9) = 9 -> 3 -> 1 = 2
  • solution(10) = 10 -> 9 -> 3 -> 1 = 3

나열하면서 발견한 점은 큰 수의 경우 작은 수의 합산임을 알 수 있다. 이를 수정해서 다시 적어보면,

  1. 3으로 나누어 떨어지면 : solution(n) = solution(n/3) + 1
  2. 2로 나누어 떨어지면 : solution(n) = solution(n/2) + 1
  3. 1을 빼면 : solution(n) = solution(n-1) + 1

입력

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

해결 방법

메모이제이션을 이용하면 된다!

# 정수 input 값 받기
num = int(input())

# 메모
value = [0 for i in range(0, num + 1)]
value[1] = 0

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

print(value[num])
profile
https://medium.com/@jinsung1048 미디엄으로 이전하였습니다.

0개의 댓글