loading
본문 바로가기
Coding/Backjoon

[ Backjoon - 1463번 ] 1로 만들기 ( java )

by NeuLyeo 2024. 1. 30.

[ Backjoon - 1463번 ] 1로 만들기 ( java )

 

1463번: 1로 만들기

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

www.acmicpc.net

 

 

 

 

📚 Table of Contents

     

     

     

     

    문제

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

     

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

     

    정수 N이 주어졌을 때, 위와 같은 연산 세 개를 적절히 사용해서 1을 만들려고 한다.

     

    연산을 사용하는 횟수의 최솟값을 출력하시오.

     

     

    입력

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

     

     

    출력

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

     

     

    예제 입력, 출력

     

     

     

     

    문제 풀이

    코드 설명

    • 코드의 목적:
      • 이 코드는 주어진 수를 1로 만드는데 필요한 최소 연산 횟수를 찾는 것입니다.
      • 연산은 세 가지 종류가 있으며, 1을 빼는 연산, 2로 나누는 연산, 3으로 나누는 연산입니다.

     

    • 코드의 주요 구조:
      • 이 코드는 입력으로 하나의 정수를 받습니다.
      • 이후, 이 정수까지의 모든 정수에 대해 1로 만드는데 필요한 최소 연산 횟수를 계산하고, 이를 배열에 저장합니다.

     

    • 코드의 주요 알고리즘:
      • 이 코드는 동적 프로그래밍(Dynamic Programming) 기법을 사용합니다.
      • 동적 프로그래밍은 큰 문제를 작은 문제로 나누어 해결하는 방법론입니다.
      • 주어진 수를 1로 만드는 가장 기본적인 방법이 1을 빼는 것입니다.
      • 그러나 2나 3으로 나누는 연산이 가능하다면, 그 연산을 수행하는 것이 더 빠르게 수를 1로 만들 수 있을 것입니다.
      • 따라서 1을 빼는 연산을 기본으로 설정하고, 다른 연산이 가능한 경우에는 그 결과와 비교하여 최소 연산 횟수를 찾는 것입니다.
      • 이 코드에서는 각 정수 i를 1로 만드는데 필요한 최소 연산 횟수를 찾기 위해 i - 1, i / 2, i / 3 각각을 1로 만드는데 필요한 연산 횟수를 비교하고, 그 중 최소값을 선택합니다.

     

    • 코드의 핵심:
      • 이 코드의 핵심은 동적 프로그래밍을 이용하여 주어진 문제를 효율적으로 해결하는 것입니다.

     

     

     

    풀이

    import java.util.Scanner;
    
    public class Backjoon_1463 {
    
        public static void main(String[] args)  {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt(); // 입력 받을 수
            int[] dp = new int[n + 1]; // 각 수를 1로 만드는데 필요한 최소 연산 횟수를 저장할 배열
    
            dp[0] = dp[1] = 0; // 0과 1은 이미 1이므로 연산이 필요 없습니다.
    
            for (int i = 2; i <= n; i++) { // 2부터 n까지 각 수를 1로 만드는데 필요한 최소 연산 횟수를 계산합니다.
                dp[i] = dp[i - 1] + 1; // 1을 빼는 연산
                if (i % 2 == 0) dp[i] = Math.min(dp[i], dp[i / 2] + 1); // 2로 나누는 연산
                if (i % 3 == 0) dp[i] = Math.min(dp[i], dp[i / 3] + 1); // 3으로 나누는 연산
            }
            sc.close(); // Scanner를 닫습니다.
    
            System.out.println(dp[n]); // 입력 받은 수를 1로 만드는데 필요한 최소 연산 횟수를 출력합니다.
        }
    }