상세 컨텐츠

본문 제목

9184. 신나는 함수 실행

Algorithm

by aeongiii 2024. 11. 14. 16:28

본문


1. 문제 분석
    1) a, b, c를 받아서 재귀함수를 실행한 뒤 출력형식에 맞게 결과를 출력한다.
    2) a, b, c = -1, -1. -1이 나올때까지 입력받는다.
    3) a, b, c 계산할때마다 배열에 저장하고, 가능한 계산된 값을 활용한다.

2. 제약 조건
   -50 <= a, b, c <= 50

3. 의사결정
    1) a, b, c가 각각 0부터 20까지인 3차원 배열을 만든다.
    2) for문을 만들고 a, b, c 입력받고, 한번 계산한 값은 저장해가면서 재귀함수를 호출한다.
        - a, b, c가 -1인 경우 프로그램 종료
        - a <= 0 or b <= 0 or c <= 0 인 경우 1 반환
        - a > 20 or b > 20 or c > 20 인 경우 w(20, 20, 20) 반환
        - a < b and b < c 인 경우 w(a, b, c-1) + w(a, b-1, c-1) - w(a, b-1, 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)로 재귀함수 호출

4. 문제 해결
    1) 처음에는 배열을 안 쓰고 해보려고 했는데 어려워서 메모이제이션 방식을 새로 배워 활용했다.
    2) for문을 통해 한번씩 입력받고 실행하는 것보다, 한번에 입력받은 뒤 순차적으로 실행하는 방식으로 수정했다.
 

+ 메모이제이션 알고리즘에 대해 오늘 따로 정리해야겠다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class Main {

    static int[][][] memo = new int[21][21][21]; // 메모이제이션

    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // 입력받은 a, b, c 저장할 리스트
        List<String> inputLine = new ArrayList<String>();


        // 한번에 입력받기
        String line;
        while (!(line = br.readLine()).equals("-1 -1 -1")) {
            inputLine.add(line);
        }

        // 입력받은 문자열을 한 줄씩 계산하고 값 출력
        for (int i = 0; i < inputLine.size(); i++) {
            String[] abc = inputLine.get(i).split(" ");
            int a = Integer.parseInt(abc[0]);
            int b = Integer.parseInt(abc[1]);
            int c = Integer.parseInt(abc[2]);

            // 출력
            System.out.printf("w(%d, %d, %d) = %d\n", a, b, c, w(a, b, c));
        }
    }

    // 재귀함수
    public static int w(int a, int b, int c) {

        // 0이하 또는 20 이상인 경우
        if(a <= 0 || b <= 0 || c <= 0) {
            return 1;
        } else if (a > 20 | b > 20 | c > 20) {
            return w(20, 20, 20);
        }

        // 이미 계산된 값이 있는 경우 활용한다.
        if (memo[a][b][c] != 0) {
            return memo[a][b][c];
        }

        // 이미 계산된 값이 없는 경우 새로 계산하고 저장한다.
        if (a < b && b < c) {
            memo[a][b][c] = w(a, b, c-1) + w(a, b-1, c-1) - w(a, b-1, c);
        } else {
            memo[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 memo[a][b][c];
    }

}

 

메모리 시간
99624 KB 2144 ms

'Algorithm' 카테고리의 다른 글

메모이제이션(Memoization)  (0) 2024.11.14
17478. 재귀함수가 뭔가요?  (1) 2024.11.14
10994. 별 찍기 - 19  (0) 2024.11.14
25501. 재귀의 귀재  (0) 2024.11.14
24416. 알고리즘 수업 - 피보나치 수 1  (0) 2024.11.14

관련글 더보기