www.acmicpc.net/problem/1463

 

1463번: 1로 만들기

첫째 줄에 1보다 크거나 같고, 106보다 작거나 같은 정수 N이 주어진다.

www.acmicpc.net

문제

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

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

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

입력

첫째 줄에 1보다 크거나 같고, 106보다 작거나 같은 정수 N이 주어진다.

출력

첫째 줄에 연산을 하는 횟수의 최솟값을 출력한다.

예제 입력 1

2

예제 출력 1

1

예제 입력 2

10

예제 출력 2

3

 

 

 

 

풀이 .

import java.util.*;
import java.io.*;

public class Main {
    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[0] = 0;
        dp[1] = 0;

        for(int i = 2; i <= n; i++) {
            int temp = n;
            if(i % 3 == 0) temp = Math.min(temp, dp[i / 3]);
            if(i % 2 == 0) temp = Math.min(temp, dp[i / 2]);
            temp = Math.min(temp, dp[i - 1]);
            dp[i] = temp + 1;
        }
        System.out.println(dp[n]);
    }
}

 

전형적인 DP 문제이다.

 

문제는 n을 1로 만들 것을 요구하지만 1을 n으로 만드는 식으로 풀어냈다.

(dp[n] = 1에서 n으로 도달하기 위한 최소 연산 회수)

 

만약 n에 1, 2, 3 모든 연산을 사용할 수 있는 수라면, n으로 올 수 있는 숫자의 경우의 수는 총 셋이다.

1. (n / 3) * 3

2. (n / 2) * 2

3. (n - 1) + 1

다시 말하면 n/3, n/2, n-1에서 한 번의 연산만 더 수행하면 n이 될 수 있는 것.

즉, dp[n / 3], dp[n / 2], dp[n - 1] 중 최솟값 + 1이 dp[n]이 될 것이다.

 

그럼 dp[n / 3], dp[n / 2], dp[n - 1] 은 또 어떻게 구하나?

n에서 했던 것처럼 각자 자신에게 올 수 있는 연산들에 대한 경우를 모두 따져보면 된다.

 

탑 다운, 바텀 업 모두 가능하지만 바텀 업 방식으로 구현했다.

+ Recent posts