다이나믹 프로그래밍을 푸는 첫 번째 과정은 DP[n] (또는 k차원의 배열]이 무엇인지를 정의하는 것이다.
일반적인 문제는 그대로 정의하면 된다.
이 문제에서는,
dp[n] = n을 1로 만드는 최소한의 연산의 수
라고 생각할 수 있다.
또, dp[n]은 dp[n-1]+1, dp[n/2] +1, dp[n/3] +1 중 하나이고,
이전 단계 즉, N-1 또는 N/2 또는 N/3 을 1로 만드는 최소한의 연산의 수 라는 조건을 만족한다면,
N을 1로만드는 최소한의 연산의 수라는 조건도 만족한다.
간단한 문제이기 때문에 바로 코드,
Top-Down 방식으로 재귀 호출로 구현한 코드이다.
d배열에 메모를 하는 방식이다.
문제는 충분히 시간 안에 해결할 수 있지만 재귀 호출의 오버헤드 문제 때문인지 Bottom-up보단 좀 오래 걸렸다
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Main { static int[] d=new int[1000001]; public static int dp(int N) { if(N==0 || N==1) return 0; if(d[N]>0) return d[N]; if(N%3==0 && N%2==0) { d[N]= Math.min(dp(N/3), Math.min(dp(N-1),dp(N/2)))+1; }else if(N%3==0) { d[N]= Math.min(dp(N/3),dp(N-1))+1; }else if(N%2==0) { d[N]= Math.min(dp(N/2), dp(N-1))+1; }else { d[N]= dp(N-1)+1; } return d[N]; } public static void main(String[] args) throws NumberFormatException, IOException { BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); int N=Integer.parseInt(br.readLine()); System.out.println(dp(N)); } }
다음은 Bottom-up -> for문 방식
전역 변수의, 재귀 호출의 부담이 없다.
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Main { public static void main(String[] args) throws NumberFormatException, IOException { BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); int N=Integer.parseInt(br.readLine()); /*bottom-up*/ int[] dp=new int[N+1]; dp[0]=0; dp[1]=0; for(int i=2; i<=N; i++) { if(i%3==0 && i%2==0) { dp[i]=Math.min(dp[i/3], Math.min(dp[i-1],dp[i/2]))+1; }else if(i%3==0) { dp[i]=Math.min(dp[i/3],dp[i-1])+1; }else if(i%2==0) { dp[i]=Math.min(dp[i/2], dp[i-1])+1; }else { dp[i]=dp[i-1]+1; } } System.out.println(dp[N]); } }
'이론 > 문제풀이' 카테고리의 다른 글
[백준 알고리즘 -11722] 가장 긴 감소하는 부분 수열 - java (Collections.reverse(), Java 8 Stream API) (0) | 2018.09.24 |
---|---|
[백준 알고리즘 - 1946] 신입사원 - java (0) | 2018.09.18 |
[백준 알고리즘 - 2632] 피자판매 - java/완전탐색(재귀호출) (0) | 2018.09.09 |
[백준 알고리즘 - 1208] 부분집합의 합 2 - java/재귀호출 (0) | 2018.09.06 |
[백준 알고리즘 - 1261] 알고스팟 (java, BFS) (0) | 2018.09.04 |