[문제 링크]
https://www.acmicpc.net/problem/9184
[난이도]
- Silver 2
[알고리즘]
- DP
[코드]
import java.io.*;
import java.util.*;
public class Main {
static int[][][] dp = new int[51][51][51];
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st;
while (true) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
if (a == -1 && b == -1 && c == -1) {
break;
}
bw.write("w(" + a + ", " + b + ", " + c + ") = " + w(a, b, c) + "\n");
}
bw.flush();
bw.close();
br.close();
}
static int w(int a, int b, int c) {
if (a <= 0 || b <= 0 || c <= 0) {
return 1;
} else if (a > 20 || b > 20 || c > 20) {
return w(20, 20, 20);
} else if (dp[a][b][c] != 0) {
return dp[a][b][c];
} else if (a < b && b < c) {
dp[a][b][c] = w(a, b, c - 1) + w(a, b - 1, c - 1) - w(a, b - 1, c);
} else {
dp[a][b][c] = w(a - 1, b, c) + w(a - 1, b - 1, c) + w(a - 1, b, c - 1) - w(a - 1, b - 1, c - 1);
}
return dp[a][b][c];
}
}
[풀이]
점화식은 이미 나와있기 때문에 고민할 필요는 없다. 다만 그대로 사용하면 시간초과가 발생한다. 이를 해결하기 위해
메모이제이션을 활용해야 한다. 함수는 다음과 같이 작성했다.
static int w(int a, int b, int c) {
if (a <= 0 || b <= 0 || c <= 0) {
return 1;
} else if (a > 20 || b > 20 || c > 20) {
return w(20, 20, 20);
} else if (dp[a][b][c] != 0) {
return dp[a][b][c];
} else if (a < b && b < c) {
dp[a][b][c] = w(a, b, c - 1) + w(a, b - 1, c - 1) - w(a, b - 1, c);
} else {
dp[a][b][c] = w(a - 1, b, c) + w(a - 1, b - 1, c) + w(a - 1, b, c - 1) - w(a - 1, b - 1, c - 1);
}
return dp[a][b][c];
}
아래 조건문을 활용하면 이미 한번 계산한 값이라면 저장해놓은 배열에서 꺼내서 사용할 수 있기 때문에 시간을 효율적으로 줄일 수 있다.
else if (dp[a][b][c] != 0) {
return dp[a][b][c];
}
아래 조건문을 활용해 계산한 값을 dp 배열에 저장해 나중에 사용할 수 있다.
else if (a < b && b < c) {
dp[a][b][c] = w(a, b, c - 1) + w(a, b - 1, c - 1) - w(a, b - 1, c);
} else {
dp[a][b][c] = w(a - 1, b, c) + w(a - 1, b - 1, c) + w(a - 1, b, c - 1) - w(a - 1, b - 1, c - 1);
}
'코딩테스트' 카테고리의 다른 글
백준 1932 : 정수 삼각형 [JAVA] (0) | 2024.06.12 |
---|---|
백준 11055 : 가장 큰 증가하는 부분 수열2 [JAVA] (0) | 2024.06.12 |
백준 1965 : 상자넣기 [JAVA] (1) | 2024.06.11 |
백준 8394: 악수 [JAVA] (0) | 2024.06.11 |
백준 9095: 1, 2, 3 더하기 [JAVA] (1) | 2024.06.08 |