기맹기 개발 블로그

[BOJ 14238] 출근 기록 (Java) 본문

PS

[BOJ 14238] 출근 기록 (Java)

기맹기 2022. 9. 12. 02:58

BOJ 14238 출근 기록

난이도 : 골드 3

https://www.acmicpc.net/problem/14238

 

14238번: 출근 기록

스타트링크에는 세명의 직원이 일을 하고 있다. 세 직원의 이름은 강호(A), 준규(B), 수빈(C) 이다. 이 회사의 직원은 특별한 룰을 가지고 있는데, 바로 하루에 한 명만 출근한다는 것이다. 3일간의

www.acmicpc.net

 

전략

S의 길이가 최대 50이므로, 모든 경우의 수를 다 탐색하면 안된다.

 

메모이제이션을 사용해서 중복된 연산을 제거해야 한다.

 

불가능한 것이 계산된 (방문된) 상태는 bool 타입의 dp 배열을 통해 검사하여 제거할 수 있다.

 

경우의 수 탐색은 재귀 호출로 구현된 dfs로 이루어진다.

 

시행착오

처음에는 dp의 기준을 dp[현재 idx][남은 a][남은 b][남은 c] 로 하고, 배열 seq의 상태를 통해 b, c를 놓을 수 있는지 확인했는데

 

이렇게 하면 배열의 상태가 계속 변하기 때문에 dp의 의미가 없어진다.

 

필요한 모든 정보를 dp에 담기 위해서는 b, c에 영향을 미치는 마지막에서 2개의 출근 기록을 고려해야한다.

 

코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    static char[] seq;
    static boolean[][][][][] dp;
    static int S;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine();
        S = str.length();
        int[] freq = new int[3];
        seq = new char[S + 1];
        dp = new boolean[S + 1][S + 1][S + 1][3][3];

        for (int i = 0; i < str.length(); i++)
            freq[str.charAt(i) - 'A']++;

        if (solution(freq[0], freq[1], freq[2], 0, 0))
            System.out.println(seq);
        else
            System.out.println(-1);
    }

    static boolean solution(int a, int b, int c, int yd2, int yd1) {
        if (a == 0 && b == 0 && c == 0) return true;

        if (dp[a][b][c][yd2][yd1]) return false;
        dp[a][b][c][yd2][yd1] = true;

        if (a > 0) {
            seq[S - a - b - c] = 'A';
            if (solution( a - 1, b, c, yd1, A)) return true;
        }
        if (b > 0 && yd1 != B) {
            seq[S - a - b - c] = 'B';
            if (solution(a, b - 1, c, yd1, B)) return true;
        }
        if (c > 0 && yd2 != C && yd1 != C) {
            seq[S - a - b - c] = 'C';
            if (solution(a, b, c - 1, yd1, C)) return true;
        }

        return false;
    }

    static final int A = 0;
    static final int B = 1;
    static final int C = 2;

}

 

깨달은 점

dp를 구성할 때 탐색에 영향을 미치는 변수들을 반드시 메모이제이션에 포함시켜야 한다고 깨달았다.

'PS' 카테고리의 다른 글

[BOJ 12100] 2048 (Easy) (Java)  (0) 2022.12.26
[BOJ 2623] 음악프로그램 (Java)  (0) 2022.12.26
[BOJ 12969] ABC (Java)  (0) 2022.09.11
[BOJ 11066] 파일 합치기 (Java)  (1) 2022.09.11
[BOJ 12869] 뮤탈리스크 (Java)  (0) 2022.09.11