나의 처음 생각
3으로 나누었을 때 나머지가 0인지, 그리고 0이 아닐 때 홀수인지 짝수인지로 구분해서 어떤 규칙을 찾아내려고 했었다
그런데 규칙 찾기에는 실패했고 숫자를 키워가면서 경우의 수를 따졌을 때 더 작은 숫자들의 나누기가 반복되는 것을 느꼈다
예를들어, 숫자 22를 갖고 연산할 때 22-> 21-> 7-> 6-> 2-> 1 에서 7을 갖고 연산할 때의 경우가 똑같이 반복되었다
구글링을 한 결과 '동적 계획법(Dynamic Programming)' 을 사용한 풀이임을 알게되었다
Bottom-Up 방식
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
int[] dp = new int[N+1];
dp[0]=0;
dp[1]=0;
for(int i=2; i<=N; i++) { // 2부터 N까지 반복문 = Bottom-Up방식
dp[i] = dp[i-1]+1; // 기본 연산 횟수는 이전 연산 횟수+1 로 설정
// %3==0 이면 더 작은수로 설정
if(i%3==0) dp[i]= Math.min(dp[i/3]+1, dp[i]);
// %2==0 이면 더 작은수로 설정
if(i%2==0) dp[i]= Math.min(dp[i/2]+1, dp[i]);
}
System.out.println(dp[N]);
}
}
다른 풀이
Top-Down 방식
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
static int[] dp;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
dp = new int[N+1];
System.out.println(recur(N));
}
static int recur (int num) {
if(num==1 | dp[num] >0) { // num이 1이거나, num의 연산 횟수가 이미 있다면
return dp[num]; // 기존 dp[num] 리턴
}
dp[num] = recur(num-1)+1; // 기본 연산 횟수를 num-1 을 recur 한 수+1 로 설정
if(num%3 ==0) { // %3==0일때
dp[num]=Math.min(recur(num/3)+1, dp[num]);
}
if(num%2 ==0) { // %2==0일때
dp[num]=Math.min(recur(num/2)+1, dp[num]);
}
return dp[num];
}
}
그런데 Top-Down 방식은 재귀함수를 사용해서 백준에서 답변으로 제출 시 시간초과가 난다
재귀를 사용하는 방법도 있지만 이 경우에는 Bottom-Up 방식이 더 효율적이다
'백준 풀이' 카테고리의 다른 글
[백준 풀이_Java] 1946 신입사원 (0) | 2021.10.23 |
---|---|
[백준 풀이_Java] 1026 보물 (0) | 2021.10.22 |
[백준 풀이_Java] 5585 거스름돈 (0) | 2021.09.02 |
[백준 풀이_Java] 15881 Pen Pineapple Apple Pen (0) | 2021.08.29 |
[백준 풀이_Java] 4344 평균은 넘겠지 (0) | 2021.08.27 |