300x250
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 프로그래밍
- 동적프로그래밍
- 딥러닝
- nlp
- 코딩
- BFS
- 네트워크
- dp
- 그래프
- 코딩테스트
- 순열
- CSS
- 백준
- OS
- 코딩 테스트
- google coding competition
- 운영체제
- 프로그래머스
- 리눅스
- 구글 킥스타트
- PYTHON
- 킥스타트
- 알고리즘
- 동적 프로그래밍
- 브루트포스
- AI
- 파이썬
- kick start
- DFS
- linux
Archives
- Today
- Total
오뚝이개발자
[백준 1463] 1로 만들기 본문
728x90
300x250
문제
https://www.acmicpc.net/problem/1463
1463번: 1로 만들기
첫째 줄에 1보다 크거나 같고, 106보다 작거나 같은 정수 N이 주어진다.
www.acmicpc.net
나의 풀이
DP를 사용해 쉽게 풀 수 있는 문제이다. input으로 주어진 각 수는 아래의 연산 중 한 가지를 할 수 있다.
- 2로 나누어 떨어지면 2로 나눈다.
- 3으로 나누어 떨어지면 3으로 나눈다.
- 1을 뺀다.
이를 반복해서 결과적으로 1이란 수를 만들어야 하는데, 이를 DP의 점화식과 연관지어 생각해보면 쉽다. 만약 내가 10이란 수를 input으로 받는다고 가정해보자.
- 10->5->4->2->1
- 10->9->3->1
- 10->9->8->7->...->1
위의 경우 말고도 10을 1로 만들기 위해선 굉장히 다양한 경우가 존재한다. 이 중 우리는 연산을 최소화하는 경우를 return해야 한다. dp라는 배열을 만들고, dp[i]에 i를 1로 만들기 위한 최소 연산의 수를 저장하자. 그럼 dp[10]=min(dp[10//2], dp[10-1]) + 1이 된다. 만약 2와 3의 공배수인 6이라면 dp[6]=min(dp[6-1], min(dp[6//2],dp[6//3]))이 된다. 이처럼 bottom-up 방식으로 쌓아나가 해당 수의 dp[x]를 구하게 되면 끝이 난다.
코드
x = int(input())
dp = [0] * (10**6 + 1)
dp[1], dp[2], dp[3] = 0, 1, 1
if x==1:
print(0)
elif x==2 or x==3:
print(1)
else:
for i in range(4,x+1):
if i%2==0 and i%3==0:
dp[i] = min(dp[i-1], min(dp[i//2], dp[i//3])) + 1
elif i%2==0:
dp[i] = min(dp[i-1], dp[i//2]) + 1
elif i%3==0:
dp[i] = min(dp[i-1], dp[i//3]) + 1
else:
dp[i] = dp[i-1] + 1
print(dp[x])
728x90
300x250
'코딩 테스트 > 백준' 카테고리의 다른 글
[백준 1504] 특정한 최단 경로 (0) | 2022.04.05 |
---|---|
[백준 13549] 숨바꼭질 3 (1) | 2022.04.02 |
[백준 1259] 팰린드롬 수 (0) | 2021.09.20 |
[백준 1013] Contact (0) | 2021.09.20 |
유레카 이론 (0) | 2021.07.13 |
Comments