백준 9184 신나는 함수 실행 [JAVA]

Ga0·2023년 10월 27일
0

baekjoon

목록 보기
102/125

문제 해석

  • 문제는 아래와 같은 케이스로 나누어 수행한다.
    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]; //a, b, c가 20이 최대이기 때문에 21(인덱스 0부터 시작)

    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()); //a 값
        int b = Integer.parseInt(st.nextToken()); //b 값
        int c = Integer.parseInt(st.nextToken()); //c 값

        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()); //a 값
            b = Integer.parseInt(st.nextToken()); //b 값
            c = Integer.parseInt(st.nextToken()); //c 값

        }

        System.out.println(sb);


        br.close();
    }

    //w(a, b, c)값을찾는 메소드
    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;
    }
}

결과

느낀 점

  • 동적계획법이 어색한 것만 빼면 크게 어려움이 없었던 문제였다.

0개의 댓글