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 |