알고리즘문제풀이

[JAVA] 백준 1463 1로 만들기 [ Dynamic Programming ]

Hindsight.. 2020. 8. 23. 19:26

전체 코드

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

public class 백준_1463_1로만들기 {

	static int N, d[];
	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		N = Integer.parseInt(br.readLine());
		d = new int[N+1];
		d[0] = 0;
		
		System.out.println(dp(N));
		
	}
	
	private static int dp(int n) {
		if(n==1) // n일땐 바로 리턴
			return 0;
		if(d[n] > 0) // d[n] 에 값이 구해질때까지 재귀
			return d[n];
		d[n] = dp(n-1) +1; // 현재값을 전 값의 +1을 넣어놓고
		if(n%2 == 0) { //N이 2로 나누어떨어지면
			int tmp = dp(n/2) +1; // N을 2로 나눈값에 한번 더 연산했으므로 + 1
			if(d[n] > tmp) // 현재값이 더 크다면 현재 값, 아니라면 위의 tmp값을 넣는다.
				d[n] = tmp;
		}
		if(n%3 == 0) { // 2로 나누어 떨어질 때와 마찬가지로
			int tmp = dp(n/3) + 1; // 3으로 나눈값에 한번 더 연산이므로 +1
			if(d[n] > tmp) // 현재값이 더 크다면 현재 값, 아니라면 위의 tmp값을 넣는다.
				d[n] = tmp;
		}
		return d[n];
	}

}

 

문제 핵심 코드

private static int dp(int n) {
	if(n==1) // n일땐 바로 리턴
		return 0;
	if(d[n] > 0) // d[n] 에 값이 구해질때까지 재귀
		return d[n];
	d[n] = dp(n-1) +1; // 현재값을 전 값의 +1을 넣어놓고
	if(n%2 == 0) { //N이 2로 나누어떨어지면
		int tmp = dp(n/2) +1; // N을 2로 나눈값에 한번 더 연산했으므로 + 1
		if(d[n] > tmp) // 현재값이 더 크다면 현재 값, 아니라면 위의 tmp값을 넣는다.
			d[n] = tmp;
	}
	if(n%3 == 0) { // 2로 나누어 떨어질 때와 마찬가지로
		int tmp = dp(n/3) + 1; // 3으로 나눈값에 한번 더 연산이므로 +1
		if(d[n] > tmp) // 현재값이 더 크다면 현재 값, 아니라면 위의 tmp값을 넣는다.
			d[n] = tmp;
	}
	return d[n];
}

 

값들을 누적해가며, 원하는 값이 나올 때 출력하는 방법이었다. DP이지만, 기억 연산법이라는 말이 더 와닿는 문제였다.