https://www.acmicpc.net/problem/1003
코드설명
DP 문제입니다.
dp[0][0] = 1; //N은 0 일때 0의 호출 횟수
dp[0][1] = 0; //N은 0 일때 1의 호출 횟수
dp[1][0] = 0; //N은 1 일때 0의 호출 횟수
dp[1][1] = 1; //N은 1 일때 1의 호출 횟수
문제에서 가장 핵심로직은,
dp[N][0] = dp[N-1][0] + dp[N-2][0];
dp[N][1] = dp[N-1][1] + dp[N-2][0];
위의 로직을 이해해야합니다.
예시를 들면,
피보나치 수 3이 들어왔다고 가정하였을때,
fibo(3) = fibonacci(3-1) + fibonacci(3-2) = fibo(2) + fibo(1) = fibo(1) + fibo(0) + fibo(1) 이 되므로써
fibo(0)은 곧 0이 1번 나오고, fibo(1) 은 1이 2번나온다는 것을 의미합니다. ( 피보나치에서 기본적으로 fibo(0)은 0을 return하고, fibo(1)은 1을 return 합니다. 문제에서 주어진 함수가 있습니다. )
코드
처음에 시간초과 난 코드입니다.
import java.util.*;
import java.io.*;
public class Main {
public static int T, N, zeroCnt, firstCnt;
public static int[] cache;
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
T = Integer.parseInt(st.nextToken());
cache = new int[41];
Arrays.fill(cache, -1);
for(int i=0;i<T; i++) {
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
zeroCnt = 0; firstCnt = 0;
fibonacci(N);
System.out.println(zeroCnt+" "+firstCnt);
}
}
public static int fibonacci(int n) {
if(n == 0) {
zeroCnt += 1;
return 0;
}
if(n == 1) {
firstCnt += 1;
return 1;
}
int ret = 0;
ret = fibonacci(n - 1) + fibonacci(n - 2);
return ret;
}
}
정답코드입니다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static int T, N;
public static int answer = 0;
public static int[][] dp;
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
T = Integer.parseInt(st.nextToken());
dp = new int[41][2];
dp[0][0] = 1; //N은 0 일때 0의 호출 횟수
dp[0][1] = 0; //N은 0 일때 1의 호출 횟수
dp[1][0] = 0; //N은 1 일때 0의 호출 횟수
dp[1][1] = 1; //N은 1 일때 1의 호출 횟수
for(int i=2;i<=40;i++) {
dp[i][0] = dp[i-1][0] + dp[i-2][0];
dp[i][1] = dp[i-1][1] + dp[i-2][1];
}
for(int i=0;i<T;i++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
System.out.println(dp[a][0] + " "+dp[a][1]);
}
}
}
Bottom-Up 방식이 아닌, 만약에 Top-Down 방식으로 할 경우입니다.
import java.util.*;
import java.io.*;
public class Main {
public static int T, N, zeroCnt, firstCnt;
public static int[] cache;
public static int[][] zeroOneCache;
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
T = Integer.parseInt(st.nextToken());
cache = new int[41];
zeroOneCache = new int[41][2];
zeroOneCache[0][0] = 1;
zeroOneCache[0][1] = 0;
zeroOneCache[1][0] = 0;
zeroOneCache[1][1] = 1;
for(int i=2; i<41; i++) {
Arrays.fill(zeroOneCache[i], -1);
}
for(int i=0;i<T; i++) {
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
int[] answer = fibonacci(N);
System.out.println(answer[0] + " "+answer[1]);
}
}
public static int[] fibonacci(int n) {
if(zeroOneCache[n][0] != -1 || zeroOneCache[n][1] != -1) {
return zeroOneCache[n];
}
int[] result1 = fibonacci(n - 1);
int[] result2 = fibonacci(n - 2);
zeroOneCache[n][0] = result1[0] + result2[0];
zeroOneCache[n][1] = result1[1] + result2[1];
return zeroOneCache[n];
}
}
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 1010 다리 놓기 - DP JAVA (0) | 2023.08.17 |
---|---|
[백준] 2748 피보나치 수 2 - DP JAVA (0) | 2023.08.16 |
[백준] 108710 피보나치 수 5 - DP JAVA (0) | 2023.08.16 |
[백준] 14891 톱니바퀴 - 구현 + 시뮬레이션 JAVA (0) | 2023.08.15 |
[백준] 9372 상근이의 여행 - 그래프 + DFS JAVA (0) | 2023.08.14 |