import java.util.*;
import java.lang.*;
import java.io.*;
class Main {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
for(int i=0; i<N; i++){
int num = Integer.parseInt(br.readLine());
int[] dp = new int[num+1];
dp[1]=1;
if(num>=2) dp[2]=2;
if(num>=3) dp[3]=4;
for(int k=4; k<=num; k++){
dp[k]=dp[k-1]+dp[k-2]+dp[k-3];
}
System.out.println(dp[num]);
}
}
}
dp[k] = dp[k-1] + dp[k-2] + dp[k-3]if(num>=2), if(num>=3)로 ArrayIndexOutOfBounds 방지// ✘ 비효율
for(int i=0; i<N; i++){
int num = Integer.parseInt(br.readLine());
int[] dp = new int[num+1]; // 매번 새로 생성
// ...
}
최댓값(11)까지만 미리 계산하면 된다.
여러 테스트 케이스에서 동일한 값을 반복 계산한다.
if(num>=2) dp[2]=2;
if(num>=3) dp[3]=4;
루프 조건으로 처리 가능하다.
import java.io.*;
class Main {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
// 최댓값 11까지 미리 계산
int[] dp = new int[12];
dp[1] = 1;
dp[2] = 2;
dp[3] = 4;
for(int i=4; i<=11; i++){
dp[i] = dp[i-1] + dp[i-2] + dp[i-3];
}
StringBuilder sb = new StringBuilder();
for(int i=0; i<T; i++){
int n = Integer.parseInt(br.readLine());
sb.append(dp[n]).append('\n');
}
System.out.print(sb);
}
}
변경 사항:
| 방법 | 시간복잡도 | 공간복잡도 | 계산 횟수 |
|---|---|---|---|
| 원본 | O(T×N) | O(N) | T번 반복 |
| 개선 | O(1) | O(1) | 1번만 |
T=100, N=11일 때: 1100번 → 11번 계산
n을 만드는 방법 = 마지막에 더한 수에 따라 분류
dp[n-1]가지dp[n-2]가지dp[n-3]가지dp[n] = dp[n-1] + dp[n-2] + dp[n-3]
1+1+1+1
1+1+2, 1+2+1, 2+1+1
2+2
1+3, 3+1
→ 총 7가지 = dp[3]+dp[2]+dp[1] = 4+2+1
#백준 #DP #동적계획법 #BOJ9095 #Java #조합론