알고리즘/백준 알고리즘(JAVA)
JAVA) 1463번 1로 만들기 - 다이나믹 프로그래밍
starmk95
2020. 7. 20. 17:21
1. Top-Down 방식
import java.util.*;
public class Main{
public static int[] memo; // memorization을 위한 배열
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
memo = new int[num+1];
memo[0] = 0;
memo[1] = 0;
System.out.println(makeOne(num));
}
public static int makeOne(int num) {
// Top-Down 방식
// D[n] : n을 1로 만들기 위해 사용되는 연산의 횟수
// 점화식 : D[n] = min(D[n/3], D[n/2], D[n-1]) + 1
if (num < 2) { // 예외처리
return 0;
}
int temp; // 연산 최소 횟수 값을 저장할 변수
if (memo[num-1] == 0) { // 부분 문제가 풀린 적이 없음
memo[num-1] = makeOne(num-1);
}
temp = memo[num-1];
if (num%2 == 0) { // 2로 나누어떨어지는 경우
if(memo[num/2] == 0) { // 부분 문제가 풀린 적이 없음
memo[num/2] = makeOne(num/2);
}
if (temp > memo[num/2]) { // 2로 나눈 경우가 연산 횟수가 더 적으면
temp = memo[num/2];
}
}
if (num%3 == 0) { // 3으로 나누어 떨어지는 경우
if(memo[num/3] == 0) { // 부분 문제가 풀린 적이 없음
memo[num/3] = makeOne(num/3);
}
if (temp > memo[num/3]) { // 3으로 나눈 경우가 연산 횟수가 더 적으면
temp = memo[num/3];
}
}
memo[num] = temp+1; // 얻은 연산 횟수 최소값을 저장
return memo[num];
}
}
2. Bottom-Up 방식
import java.util.*;
public class Main{
public static int[] memo; // memorization을 위한 배열
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
memo = new int[num+1];
memo[0] = 0;
memo[1] = 0;
System.out.println(makeOne(num));
}
public static int makeOne(int num) {
// Bottom-Up 방식
// D[n] : n을 1로 만들기 위해 사용되는 연산의 횟수
// 점화식 : D[n] = min(D[n/3], D[n/2], D[n-1]) + 1
for (int i=2;i<num+1;i++) {
memo[i] = memo[i-1] + 1; // n-1의 경우
if (i%2 == 0) { // n/2의 경우
if (memo[i/2] + 1 < memo[i]) {
memo[i] = memo[i/2] + 1;
}
}
if (i%3 == 0) { // n/3의 경우
if (memo[i/3] + 1 < memo[i]) {
memo[i] = memo[i/3] + 1;
}
}
}
return memo[num];
}
}