카테고리 없음
[python][백준/BOJ] 1463번 : 1로 만들기
haju
2023. 7. 5. 15:20
https://www.acmicpc.net/problem/1463
1463번: 1로 만들기
첫째 줄에 1보다 크거나 같고, 106보다 작거나 같은 정수 N이 주어진다.
www.acmicpc.net
✅ 문제 풀이
- 처음 푸는 DP 문제라서 다른 풀이를 보고도 이해를 못했었다가 드디어 풀었다. 😎😎😎
- bottom - up , 상향식 방식으로 풀었다.
- 문제를 풀기위한 식을 세우기 위해 숫자 하나씩 필요한 최소 횟수를 생각해보자.
- 1 ➡ 0 (1은 1로 만들기 위한 횟수가 필요없으므로 횟수가 0이다.)
- 2 ➡ 1 (2-1 이나 2//2 로 1을 만들 수 있으므로 횟수가 1)
- 3 ➡ 1
- 4 ➡ 2 (4//2 ➡ 2//2 or 2-1)
- 5 ➡ 3 (5-1 ➡ 4//2 ➡ 2//2) or (5-1 ➡ 4-1 ➡ 3//3) 방법은 다르나 최소횟수는 똑같이 3 !
- 6 ➡ 2 (6//2 ➡ 3//3)
- 7 ➡ 3
- 8 ➡ 3
- 9 ➡ 2
- 10 ➡ 3
- 10을 예시로 보면, 10 ➡ 9 ➡ 3 ➡ 1 의 과정이 최소 횟수인데,
- 과정을 둘로 나누어 볼 수 있다. 10 ➡ (9 ➡ 3 ➡ 1)
- 10에서 1을 빼서 9로 갈 때의 횟수 == 1
- 9가 1이 되는 최소 경우 (이 횟수를 미리 알고 있어야 함) == 2
- 이 과정에서 알 수 있는 점화식
f[x] = min(f[x-1], f[x//2], f[x//3]) + 1
✅ 최종 코드
import sys
n=int(sys.stdin.readline())
#횟수를 저장할 dp 리스트
#범위를 0~n까지가 아니라 n+1로 설정한 이유는 dp[1]을 1의 최소 횟수로 설정하기 위해서
#따라서 dp[0]은 그냥 쓰지 않는 값이다!
dp=[0 for _ in range(n+1)]
#반복문을 돌면서 2부터 n까지의 최소 횟수를 리스트에 저장한다.
for i in range(2,n+1):
#현재 i의 최소 횟수는 1을 빼준 값으로 설정
dp[i]=dp[i-1]+1
#만약 i가 2의 배수일 경우, 1을 빼줘서 최소 횟수를 구한 값과 2로 나누어 최소 횟수를 구한 값을 비교해 작은 값을 저장한다.
if i%2==0:
dp[i]=min(dp[i],dp[i//2]+1)
# 만약 i가 3의 배수일 경우, 2로 나누어 최소 횟수를 구한 값(이미 저장되어 있음)과 3으로 나누어 최소 횟수를 구한 값을 비교해 작은 값을 저장한다.
if i%3==0:
dp[i]=min(dp[i],dp[i//3]+1)
#구하고자 하는 n의 횟수를 출력함
print(dp[n])