본문 바로가기
Coding Test/백준 알고리즘 풀이

[백준] 1463 1로 만들기 (자바) : DP

by CSEGR 2024. 8. 24.
728x90

✔️ 문제 설명

더보기

문제

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

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

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

입력

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

출력

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

예제 입력 1 

2

예제 출력 1 

1

예제 입력 2 

10

예제 출력 2 

3

힌트

10의 경우에 10 → 9 → 3 → 1 로 3번 만에 만들 수 있다.

 

✔️ 문제 풀이 

 

[알고리즘 정리] DP(Dynamic Programming) : 동적 계획법

✔️ DP(Dynamic Programming) 정의DP(Dynamic Programming) 이란?다이나믹 프로그래밍은 하나의 큰 문제를 여러 개의 작은 문제로 나눈 다음, 그 결과를 저장하여 다시 큰 문제를 해결할 때 사용한다.  ✔️

cse-gr.tistory.com

이전 포스팅에서 DP 알고리즘을 설명하면서 언급했던 문제이다. 

왜 DP 알고리즘을 써야하는지에 대해서는 위의 포스팅에 자세히 설명해 두었다! 

 

10->1 의 최솟값 = (9->1의 최소 연산 횟수 +1, 5->1의 최소 연산 횟수 +1)의 최소값

12->1 의 최솟값 = (11->1의 최소 연산 횟수 +1, 6->1의 최소 연산 횟수 +1, 4->1의 최소 연산 횟수 +1)의 최소값

...

=> dp[i] = min(dp[i-1]+1, dp[i/2]+1, dp[i/3]+1) 이런 점화식을 세웠다. 

 

경우의 수로

1. 3과 2로 모두 나누어 떨어지는 경우 

2. 3으로만 나누어 떨어지는 경우

3. 2로만 나누어 떨어지는 경우

4. 3과 2로 나누어 떨어지지 않는 경우 

이렇게 4가지가 있다.

 

조건문으로 4가지로 나눌 수도 있지만, 아래의 풀이로 풀었다. 

 

1. 1을 빼는 연산이 연산 횟수가 가장 작다고 가정

2. 현재 숫자가 2로 나누어 떨어지면, 1을 빼는 연산과 2로 나누는 연산 중 연산 횟수가 더 적은 방법으로 저장

3. 현재 숫자가 3으로 나누어 떨어지면, 1을 빼는 연산과 3로 나누는 연산 중 연산 횟수가 더 적은 방법으로 저장

 

이렇게 하면, 4가지 경우의 수를 모두 검사할 수 있다. 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

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[1] = 0; //1을 1로 만들기 위해 필요한 최소 연산 횟수 = 0

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

        System.out.println(dp[n]);

    }
}
728x90