1로 만들기 (교재 217p)
난이도 ●◐○ | 풀이 시간 20분 | 시간 제한 1초 | 메모리 제한 128MB
문제정수 X가 주어질 때 정수 X에 사용할 수 있는 연산은 다음과 같이 4가지이다.
- X가 5로 나누어떨어지면, 5로 나눈다.
- X가 3으로 나누어떨이지면, 3으로 나눈다.
- X가 2로 나누어떨어지면, 2로 나눈다.
- X에서 1을 뺀다.
정수 X가 주어졌을 때, 연산 4개를 적절히 사용해서 1을 만들려고 한다. 연산을 사용하는 횟수의 최솟값을 출력하시오.
입출력 조건)
입력 조건 | 첫째 줄에 정수 X가 주어진다. (1 ≤ X ≤ 30,000) |
출력 조건 | 첫째 줄에 연산을 하는 횟수의 최솟값을 출력한다. |
입출력 예시)
입력 예시 | 출력 예시 |
26 | 3 |
문제 풀이 방법
이 문제를 점화식으로 표현해보면 아래와 같다.
$a_{i}=min(a_{i-1},a_{i/2},a_{i/3},a_{i/5})+1$
소스 코드
package exam08_dynamic_programming;
import java.io.*;
public class Q1_MakeOne {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int x = Integer.parseInt(br.readLine());
int[] a = new int[x+1];
a[1] = 0;
a[2] = 1;
for (int i = 3; i < a.length; i++) {
a[i] = a[i-1] + 1; // 일단, 1을 뺀다. 그리고 1을 뺀 연산을 한 횟수 1을 더한다.
/* 각각 5 또는 3 또는 2로 나누어지는 경우,
* 1을 뺀 것과 바로 나누어 연산했을 때의 횟수를 비교하여 최솟값을 저장한다.
*
* 5,3,2 모두 나누어질 경우도 있으므로, else if를 사용하지 않고
* if를 사용함으로써 저장되어있는 값과 해당 연산의 최솟값을 비교한다.
* */
if (i % 5 == 0)
a[i] = Math.min(a[i], a[i / 5] + 1);
if (i % 3 == 0)
a[i] = Math.min(a[i], a[i / 3] + 1);
if (i % 2 == 0)
a[i] = Math.min(a[i], a[i / 2] + 1);
}
bw.write(a[x]+"\n");
br.close();
bw.close();
}
}
반응형
'자료구조&알고리즘 > 동적 프로그래밍' 카테고리의 다른 글
[백준] 동적 프로그래밍 - 9465번 스티커 (Java) (0) | 2020.11.12 |
---|---|
[이.코.테] Chapter 08 동적 프로그래밍 - 효율적인 화폐 구성 (java) (1) | 2020.11.10 |
[이.코.테] Chapter 08 동적 프로그래밍 - 바닥공사 (java) (0) | 2020.11.06 |
[이.코.테] Chapter 08 동적 프로그래밍 - 개미 전사 (java) (0) | 2020.11.06 |
[이.코.테] Chapter 08 다이나믹 프로그래밍 (0) | 2020.11.05 |
댓글