🔅코딩테스트 공부🔅/❗백준
[백준] 1463번 1로 만들기(python)
윤무무
2023. 2. 16. 18:08
https://www.acmicpc.net/problem/1463
1463번: 1로 만들기
첫째 줄에 1보다 크거나 같고, 106보다 작거나 같은 정수 N이 주어진다.
www.acmicpc.net
1. 내가 작성한 코드
import sys
num = int(sys.stdin.readline().rstrip())
dp = [0,0,1,1]
dp = dp + [0] * (num-3)
if num >= 4:
for n in range(4,num+1):
if n % 2 == 0 and n % 3 == 0: #2,3 모두 나누어 떨어지는 경우
dp[n] = 1 + min(dp[n//2],dp[n//3],dp[n-1])
elif n % 2 == 0: #2로만 나누어 떨어지는 경우
dp[n] = 1 + min(dp[n//2],dp[n-1])
elif n % 3 == 0: #3으로만 나누어 떨어지는 경우
dp[n] = 1 + min(dp[n//3],dp[n-1])
else: #2,3모두 나누어 떨어지지 않는 경우
dp[n] = 1 + dp[n-1]
print(dp[num])
n을 1로 만들 때까지 걸리는 횟수의 최솟값을 출력해주면 되는 문제이다.
이 문제의 포인트는 2나 3으로 나누어 떨어질 때 무작정 나누기를 진행하면 최적의 값을 찾을 수 없다는 것이다.
ex) n = 10
5(10 % 2) => 4(5 - 1) => 2(4 % 2) => 1(2 % 2) (4회) 최적 x
9(10-1) => 3(9%3) => 1(3%3) (3회) 최적 o
2. 문제 해결 및 수정 코드
1을 뺀 경우, 2로 나눈 경우, 3으로 나눈 경우의 min 값을 구하면 된다.
나는 아래와 같이 4가지의 경우를 나눠서 조건문을 만들었고, 꽤나 비효율적이라는 걸 느꼈지만,, 그냥 풀었다,,
1) 2,3 모두 나누어 떨어지지 않는 경우
2) 2로만 나누어 떨이지는 경우
3) 3으로만 나누어 떨어지는 경으
4) 2,3 모두 나누어 떨어지는 경우
num = int(input())
dp = [0,0,1,1]
dp = dp + [0] * (num-3)
if num >= 4:
for n in range(4,num+1):
dp[n] = 1 + dp[n-1]
if n % 2 == 0:
dp[n] = min(dp[n//2]+1,dp[n])
if n % 3 == 0:
dp[n] = min(dp[n//3]+1,dp[n])
print(dp[num])
위 코드처럼 단순하게 구현할 수 있다.