문제
정수 X에 사용할 수 있는 연산은 다음과 같이 세 가지 이다.
- X가 3으로 나누어 떨어지면, 3으로 나눈다.
- X가 2로 나누어 떨어지면, 2로 나눈다.
- 1을 뺀다.
정수 N이 주어졌을 때, 위와 같은 연산 세 개를 적절히 사용해서 1을 만들려고 한다. 연산을 사용하는 횟수의 최솟값을 출력하시오.
입력
첫째 줄에 1보다 크거나 같고, 106보다 작거나 같은 정수 N이 주어진다.
출력
첫째 줄에 연산을 하는 횟수의 최솟값을 출력한다.
풀이
전형적인 특정값에 최소로 도달하는 DP문제이다. 반대로 생각해서 1부터 N까지 도달하는 최소의 과정을 구하면 된다고 생각했다. +1, *2, *3의 방법이 있고 그걸 이용해서 코드를 짜게되면 아래와 같다.그리고 추가로 시간제한은 0.15초로 1500만번, 즉 O(n)복잡도로 풀어야한다. DP는 이걸 충족을 시켜준다추가로 메모리 제한은 128MB인데 약 3000만번 넘는 정수형을 저장할 수 있기에 문제가 되지않는다.(10의 6승은 1000만)
예제 입력 예시
10
예제 출력 예시
3
10 -> 9 -> 3 -> 1
소스코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
//1463번 1로 만들기
public class P1463 {
public static void main(String args[]) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
int dp[] = new int[N+1];
dp[1] = 0;
for (int i = 2; i <= N; i++) {
dp[i] = i;
}
//3가지 방법(1더하기, 2곱하기, 3곱하기)
for (int i = 1; i <=N; i++) {
if(i+1<=N) dp[i+1] = Math.min(dp[i+1], dp[i]+1);
if(i*2<=N) dp[i*2] = Math.min(dp[i*2], dp[i]+1);
if(i*3<=N) dp[i*3] = Math.min(dp[i*3], dp[i]+1);
}
System.out.println(dp[N]);
}
}
문제 출처
https://www.acmicpc.net/problem/1463
'알고리즘 > 자바' 카테고리의 다른 글
[백준 알고리즘] 1806번 자바(Java) 부분합 (2) | 2023.10.02 |
---|---|
[백준 알고리즘] 2206번 자바(Java) 벽 부수기 (0) | 2023.10.01 |
[백준 알고리즘] 2096번 자바(Java) 내려가기 (0) | 2023.09.30 |
[백준 알고리즘] 16935번 자바(Java) A → B (0) | 2023.09.13 |
[백준 알고리즘] 11725번 자바(Java) 트리의 부모 찾기 (0) | 2023.08.31 |