본문 바로가기

알고리즘

백준 1463번 1로 만들기 자바 풀이

728x90
반응형

 

❓문제

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

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

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


🔠 입력

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

 

🖨️출력

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


✍️ 예제 입력

2

✔️ 예제 출력

1

✍️ 예제 입력

10

✔️ 예제 출력

3

 


💡해설

숫자 x를 입력받은 후 x에서 1로 만들 때 최소 횟수를 구하는 문제이다.

3으로 나누거나, 2로 나누거나, 1을 빼는 세 가지 경우의 수가 있다.

하향식으로 계산하는 것이 아닌 상향식으로 계산해야 한다.

 

1에서부터 x까지 가는 최소횟수를 구하는 것이다.

1부터 x까지 배열을 만들어 놓고 각각 최소 횟수를 구하면 된다.

 

1 = 0; 2 = 1; 3 = 1이다.

그 이후의 숫자는 2로 나눠지는 숫자는 1을 빼거나 2로 나눠지는 것 중 작은 횟수, 

3으로 나눠지는 숫자는 1을 빼거나 3으로 나눠지는 것 중 작은 횟수를 고르면 된다. 

 

상향식이므로 1을 빼는 것이 아닌 1을 더한 후 체크한다.

arr[i/2]+1, arr[i/3]+1이 나온이유

 

10의 경우 9 3 1 로 간다.

9의 경우 3 1 로 간다.

즉, 이전에 9가 이미 최소횟수를 구해놨기 때문에 9의 최소횟수 + 1을 하면 해당 숫자의 최소횟수를 구할 수 있기 때문에 저런 공식이 나온다. 

 

import java.util.Scanner;

public class Main {
    
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        int x = sc.nextInt();

        int arr[] = new int[x+1];

        arr[0] = arr[1] = 0;

        for(int i = 2; i <= x; i++) {
            arr[i] = arr[i-1] + 1;
            if(i % 2 == 0) arr[i] = Math.min(arr[i], arr[i/2] + 1);
            if(i % 3 == 0) arr[i] = Math.min(arr[i], arr[i/3] + 1);
        }

        System.out.println(arr[x]);
   
    }
}
 

 

728x90
반응형