문제 정보

풀이

문제에서 점화식이 주어지므로 이를 그대로 사용해 재귀로 구현하면 된다. 다만 중복 호출이 많이 발생하므로 메모이제이션을 적용한다.

a,b,c의 유효 범위가 1부터 20까지로 제한되므로 int dp[21][21][21]을 사용한다.

코드

import java.io.*;
import java.util.*;
 
public class Main {
    private static int[][][] dp;
    public static void main(String[] args) throws IOException {
        dp = new int[21][21][21];
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        
        int a = 0, b = 0, c = 0;
        
        StringBuilder sb = new StringBuilder();
        while (true) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            a = Integer.parseInt(st.nextToken());
            b = Integer.parseInt(st.nextToken());
            c = Integer.parseInt(st.nextToken());
            
            if (a == -1 && b == -1 && c == -1)
                break;
            
            sb.append("w(")
                .append(a).append(", ")
                .append(b).append(", ")
                .append(c).append(") = ")
                .append(w(a, b, c))
                .append("\n");
        }
        
        bw.write(sb.toString());
        bw.flush();
        bw.close();
    }
    
    private static int w(int a, int b, int c) {
        if (a <= 0 || b <= 0 || c <= 0)
            return 1;
        
        if (a > 20 || b > 20 || c > 20) {
            dp[20][20][20] = w(20, 20, 20);
            return dp[20][20][20];
        }
        
        if (dp[a][b][c] != 0)
            return dp[a][b][c];        
        
        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);
            return dp[a][b][c];
        }
        
        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];
            
    }
}