https://www.acmicpc.net/problem/1463


문제

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

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

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


풀이

1) 문제를 한글로 풀어본다.

  • D(N) = N을 1로 만드는데 필요한 최소 연산 횟수
  • 1번 연산 : D(N/3) + 1      // +1 의미 : 해당 연산을 1회 했으므로, 1을 더함.
  • 2번 연산: D(N/2) + 1
  • 3번 연산: D(N-1) + 1


2) 점화식을 만든다.

  • D(N) = min( 1번 연산, 2번 연산, 3번 연산)


3) 코딩

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

/**
* 문제
* 정수 X에 사용할 수 있는 연산은 다음과 같이 세 가지 이다.
*
* X가 3으로 나누어 떨어지면, 3으로 나눈다.
* X가 2로 나누어 떨어지면, 2로 나눈다.
* 1을 뺀다.
* 정수 N이 주어졌을 때, 위와 같은 연산 세 개를 적절히 사용해서 1을 만들려고 한다.
* 연산을 사용하는 횟수의 최소값을 출력하시오.
*
* 입력
* 첫째 줄에 1보다 크거나 같고, 10^6보다 작거나 같은 자연수 N이 주어진다.
*
* 출력
* 첫째 줄에 연산을 하는 횟수의 최소값을 출력한다.
*
* 예제 입력 1
* 2
* 예제 출력 1
* 1
* 예제 입력 2
* 10
* 예제 출력 2
* 3
* 힌트
* 10의 경우에 10 -> 9 -> 3 -> 1 로 3번 만에 만들 수 있다.
*/
public class BOJ_1463_1로_만들기_성공 {

static int[] dp = new int[1000001];


public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(in.readLine());
int result = 0;

result = makeOne(n);
System.out.println(result);
}

private static int makeOne(int n) {
dp[0] = 0;
dp[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);
}

return dp[n];
}
}


'ALGORITHM > DP' 카테고리의 다른 글

10844번 - 쉬운 계단 수  (0) 2018.07.23
11052번 - 붕어빵 판매하기  (0) 2018.07.21
11727번 - 2×n 타일링 2  (0) 2018.07.21
11726번 - 2×n 타일링  (0) 2018.07.21

+ Recent posts