-
Q. 3316 자바 : 동아리실 관리하기(D4)코딩테스트/SWEA_Java 2023. 1. 22. 22:52
문제: https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWBnFuhqxE8DFAWr
D4 난이도의 문제이고, DP, 메모제이션을 이용한 문제이다.
최근에 DP 알고리즘을 공부중이긴 하지만,
문제를 보고 A, B, C, D를 비트로 변경해서 저장하는 방법까지는 접근을 했지만
이후 꽤 오랜 시간동안 고민했지만 푸는 방법을 모르겠어서
다른분들의 코드를 참고해서 내 방식으로 바꿔서 풀었다.
먼저 A, B, C, D의 포함 여부를 4개의 비트로 쪼개서 생각한다.
만약 A만 동아리 활동에 참여할 경우 0001(2),
D와 A가 참여할 경우 1001(2) = 9(10)으로 생각하면 된다.
이런식으로 데이터를 다룬다고 생각한 다음
이 문제를 푸는데 가장 중요한 내용은 for문 내부에 있는 if문이라고 생각한다.
if ((i & admin) != 0 && (i & 1) != 0) { dp[day][i] = 1; }
day가 0일 때 처음 열쇠는 A가 가지고 또한 활동의 책임자도 포함되어야 하므로
A와 책임자가 모두 포함된 내용들을 dp[0][1~15]에 넣는다.
이 때 배열의 첫 번째 값(0)은 날짜, 두 번째 값은 그 날 나올 수 있는 동아리원(1~15)를 의미한다.
1 ~ 15 (10) = 0001 ~ 1111(2)이므로 동아리원이 해당하는 날짜에 나올수 있는 모든 경우의 수를 표현할 수 있다.
이후 dp[1]부터는 이전 조건을 만족하는 동아리원(dp[0][1~15]중 0이아닌 배열)을 가져온 뒤
다음 날의 조건을 충족하는지 계산한다. 그 내용이 아래 조건식이다.(admin은 해당 날짜의 책임자)
if (dp[day-1][i] != 0) { for (int j=1; j<16; j++) { if ((i & j) != 0 && (j & admin) != 0) { dp[day][j] += dp[day-1][i]; dp[day][j] %= 1000000007; } } }
위 내용들을 합치면 아래와 같은 코드를 작성할 수 있다.
import java.io.BufferedReader; import java.io.InputStreamReader; class Solution { public static void main(String args[]) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int T = Integer.parseInt(br.readLine()); StringBuffer sb = new StringBuffer(); for(int test_case = 1; test_case <= T; test_case++) { sb.append('#').append(test_case).append(' '); char[] schoolChar = br.readLine().toCharArray(); int[][] dp = new int[10001][16]; int result = 0; for (int day=0; day<schoolChar.length; day++) { int admin = 1 << (schoolChar[day] - 'A'); for (int i=1; i<16; i++) { if (day == 0) { if ((i & admin) != 0 && (i & 1) != 0) { dp[day][i] = 1; } continue; } if (dp[day-1][i] != 0) { for (int j=1; j<16; j++) { if ((i & j) != 0 && (j & admin) != 0) { dp[day][j] += dp[day-1][i]; dp[day][j] %= 1000000007; } } } } } for (int i=1; i<16; i++) { result += dp[schoolChar.length-1][i]; result %= 1000000007; } sb.append(result).append('\n'); } System.out.println(sb); } }
반응형'코딩테스트 > SWEA_Java' 카테고리의 다른 글
Q. 1991 자바 : 트리 순회 (0) 2023.04.13 Q. 1868 파핑파핑 지뢰찾기(D4) (0) 2023.03.15 다익스트라(Dijkstra) 구현_Java (2) 2023.02.25 Q. 1767 자바 : 프로세서 연결하기 (2) 2023.01.31 삼성 DX 알고리즘 역량 강화 특강 지원 (0) 2023.01.12