Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 구현
- 분리 집합
- kruskal
- DFS
- 알고리즘
- union-find
- 누적 합
- Java
- kapt
- SCC
- 그래프
- BFS
- Linux
- 투 포인터
- 페르마 소정리
- MST
- BindingAdapter
- springdoc
- 백트래킹
- 이분 탐색
- concurreny
- tarjan
- Meet in the middle
- spring boot
- 위상 정렬
- MySQL
- 위상정렬
- DP
- miller-rabin
- disjoint set
Archives
- Today
- Total
기맹기 개발 블로그
[BOJ 14238] 출근 기록 (Java) 본문
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 |