1463

hoonding·2022년 5월 12일
1

Algorithm

목록 보기
1/2

1463

<문제>

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

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

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


먼저 3으로 나누어떨어지게 만드는게 제일 횟수를 줄일 수있다고 생각해서

if(3나누어떨어지면) 

else if(2로나누어떨어지면)

else 1로 빼기

이런식으로 접근해보았다. 하지만 여러 경우의 수 쭉 접근해본 결과 절대 위의 접근방식으로는 풀 수 없었다.

ex) 10

10 → 5 → 4 → 2→ 1 : 4번

10 → 9 → 3 → 1 : 3번.

이런식으로 1을 먼저빼는게 더 연산횟수를 줄일 수 있다.

따라서 이런식으로 최소 연산 횟수를 DP방식으로 Memoization하면서 접근하는게 맞다고 봤다.

ex) 18

  1. 3으로나누기 18 / 3 = 6
  2. 2로 나누기 18 / 2 = 9
  3. 1로 빼기 18 -1 = 17

이런식으로 3가지 연산을 할 수 있다.

만약 우리가 6, 9 ,17의 연산횟수를 미리 알고 있다면

저 중에서 가장 연산횟수가 작은 놈을 선택하면 최소로 구할 수 있을것이다.

num = int(input())
dp = []
dp.append(0) #! 0
dp.append(0) #! 1
dp.append(1) #! 2
dp.append(1) #! 3

def find_min_num(num):
    for i in range(4,num+1):      
        if (i%3 == 0 and i%2 == 0):
            dp.append(min(dp[i-1]+1,dp[i//3]+1,dp[i//2]+1))
        elif i%3 == 0:
            dp.append(min(dp[i-1]+1,dp[i//3]+1))
        elif i%2 == 0:
            dp.append(min(dp[i-1]+1,dp[i//2]+1))
        else : 
            dp.append(dp[i-1]+1)
            
            
find_min_num(num)
print(dp[num])

DP

  • 그 전의 결과들을 저장해놓고 그 저장해놓은 값을 활용하여 결과를 내는것.

0개의 댓글