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 | 
                            Tags
                            
                        
                          
                          - 백트래킹
 - union-find
 - SCC
 - 알고리즘
 - BFS
 - Meet in the middle
 - tarjan
 - concurreny
 - Linux
 - miller-rabin
 - DFS
 - 위상 정렬
 - 페르마 소정리
 - 투 포인터
 - springdoc
 - 구현
 - disjoint set
 - 이분 탐색
 - 누적 합
 - 위상정렬
 - spring boot
 - kruskal
 - 그래프
 - MST
 - BindingAdapter
 - kapt
 - 분리 집합
 - Java
 - MySQL
 - DP
 
                            Archives
                            
                        
                          
                          - Today
 
- Total
 
기맹기 개발 블로그
[BOJ 12969] ABC (Java) 본문
BOJ 12969 ABC
난이도 : 골드 1
https://www.acmicpc.net/problem/12969
12969번: ABC
첫째 줄에 문제의 조건을 만족하는 문자열 S를 출력한다. 가능한 S가 여러 가지라면, 아무거나 출력한다. 만약, 그러한 S가 존재하지 않는 경우에는 -1을 출력한다.
www.acmicpc.net
전략
'A'의 개수 a, 'B'의 개수 b로 이루어진 길이가 len인 문자열에서 조건을 만족하는 쌍이 pair만큼 있다면
len + 1 길이의 문자열에서의 pair은 다음과 같다.
1. 'A' 선택 : pair
2. 'B' 선택 : pair + a
3. 'C' 선택 : pair + a + b
이전 길이의 문자열에서의 'A', 'B', 'C'의 위치와 관계 없이 개수 a, b에 따라 다음 길이 문자열의 pair이 결정되므로
중복되는 연산을 제거할 수 있다.
시행착오
dp에서 항상 특정 상태에서 최적의 값을 저장하다가,
문제의 특이한 구조로 어떻게 저장해야할지 고민이 많이 되었다.
처음에는 dp[len][a][b]의 3차원 배열에 int형으로 pair를 저장하려고 했지만
반환 처리를 어떻게 할지 고민하다가 이렇게 구성하였다.
코드
import java.util.Scanner;
public class Main {
    static int N, K;
    static char[] seq;
    static boolean[][][][] dp;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        N = sc.nextInt();
        K = sc.nextInt();
        seq = new char[N + 1];
        dp = new boolean[N + 1][N + 1][N + 1][N * (N - 1) / 2 + 1];
        if (solution(0, 0, 0, 0))
            System.out.println(seq);
        else
            System.out.println(-1);
    }
    static boolean solution(int len, int a, int b, int pairs) {
        if (len == N) {
            if (pairs == K)
                return true;
            return false;
        }
        if (dp[len][a][b][pairs])
            return false;
        dp[len][a][b][pairs] = true;
        seq[len] = 'A';
        if (solution(len + 1, a + 1, b, pairs)) return true;
        seq[len] = 'B';
        if (solution(len + 1, a, b + 1, pairs + a)) return true;
        seq[len] = 'C';
        if (solution(len + 1, a, b, pairs + a + b)) return true;
        return false;
    }
}
깨달은 점
메모이제이션으로 중복 연산을 줄이는 방법이 바로바로 떠오를 때까지 열심히 연습해야겠다.
'PS' 카테고리의 다른 글
| [BOJ 2623] 음악프로그램 (Java) (0) | 2022.12.26 | 
|---|---|
| [BOJ 14238] 출근 기록 (Java) (0) | 2022.09.12 | 
| [BOJ 11066] 파일 합치기 (Java) (1) | 2022.09.11 | 
| [BOJ 12869] 뮤탈리스크 (Java) (0) | 2022.09.11 | 
| [BOJ 10422] 괄호 (Java) (0) | 2022.09.09 |