문제 해석
- 문제는 아래와 같은 케이스로 나누어 수행한다.
if a <= 0 or b <= 0 or c <= 0, then w(a, b, c) returns:
1
if a > 20 or b > 20 or c > 20, then w(a, b, c) returns:
w(20, 20, 20)
if a < b and b < c, then w(a, b, c) returns:
w(a, b, c-1) + w(a, b-1, c-1) - w(a, b-1, c)
otherwise it returns:
w(a-1, b, c) + w(a-1, b-1, c) + w(a-1, b, c-1) - w(a-1, b-1, c-1)
- 이 문제의 카테고리가 동적 계획법으로써 메모이제이션기술을 사용한다.
- 메모이제이션 : 컴퓨터 프로그램이 동일한 계산을 반복해야할 때 이전에 계산한 값을 미리 저장함으로써, 동일한 계산을 피해 프로그램 속도를 빠르게 하는 기술을 말한다.
- 이 문제는 2차원 배열을 사용하여 이전에 계산한 값을 미리 저장하였다.
코드
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.StringTokenizer;
public class Main {
static int[][][] result = new int[21][21][21];
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
StringTokenizer st;
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
while (!(a == -1 && b == -1 && c == -1)) {
sb.append("w(" + a + ", " + b + ", " + c + ") = ");
sb.append(solution(a, b, c)).append("\n");
st = new StringTokenizer(br.readLine());
a = Integer.parseInt(st.nextToken());
b = Integer.parseInt(st.nextToken());
c = Integer.parseInt(st.nextToken());
}
System.out.println(sb);
br.close();
}
static int solution(int a, int b, int c) {
if (validCheck(a, b, c) && result[a][b][c] != 0) {
return result[a][b][c];
} else if (a <= 0 || b <= 0 || c <= 0) {
return 1;
} else if (a > 20 || b > 20 || c > 20) {
return result[20][20][20] = solution(20, 20, 20);
} else if (a < b && b < c) {
return result[a][b][c] = solution(a, b, c - 1) + solution(a, b - 1, c - 1) - solution(a, b - 1, c);
}
return result[a][b][c] = solution(a - 1, b, c) + solution(a - 1, b - 1, c) + solution(a - 1, b, c - 1) - solution(a - 1, b - 1, c - 1);
}
static boolean validCheck(int a, int b, int c) {
return 0 <= a && a <= 20 && 0 <= b && b <= 20 && 0 <= c && c <= 20;
}
}
결과
느낀 점
- 동적계획법이 어색한 것만 빼면 크게 어려움이 없었던 문제였다.