https://www.acmicpc.net/problem/9658
코드설명
동적계획법(DP, Dynamic Programming) + 게임이론(Game Theory)을 활용합니다.
고민했었던점은, Cache에서 초기값을 -3말고 -2나 2로 두어도 괜찮을까? 라는 생각이 있었습니다.
가능합니다. 이유는, 해당 -2와 2가 이미 "불가능한 경우"를 의미하기 때문입니다.
그렇지만, 좀 더 명확한 표현을 위해 cache에서 초기값을 둘 때 -2와 2를 사용하지 않고, -3을 사용하여 한번도 계산되지 않음을 표현합니다.
코드
package Main;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.StringTokenizer;
public class Main {
private static int N, T, M;
private static int answer = 0;
private static int[][] cache;
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
cache = new int[2][N+1];
for(int i=0;i<=1;i++) {
Arrays.fill(cache[i], -3);
}
answer = game(0, N);
// System.out.println(answer);
System.out.println(answer > 0 ? "SK" : "CY");
}
public static int game(int level, int stones) {
//만약 돌이 없는 상태라면, 게임이 끝난상태다.
if(stones <= 0) {
//만약 선공차례에 돌이 없는상태라면, 선공이 이긴다.
return level % 2 == 0 ? 1 : -1;
}
if(cache[level%2][stones] != -3) return cache[level%2][stones];
//만약 선공차례라면,
int bestChoice;
if(level % 2 == 0) {
int ret1 = -2, ret2 = -2, ret3 = -2;
if(stones >= 1)
ret1 = game(level + 1, stones -1);
if(stones >= 3)
ret2 = game(level + 1, stones - 3);
if(stones >= 4)
ret3 = game(level + 1, stones - 4);
bestChoice = Math.max(ret1, Math.max(ret2, ret3));
}
else {
int ret1 = 2, ret2 = 2, ret3 = 2;
if(stones >= 1)
ret1 = game(level + 1, stones -1);
if(stones >= 3)
ret2 = game(level + 1, stones - 3);
if(stones >= 4)
ret3 = game(level + 1, stones - 4);
bestChoice = Math.min(ret1, Math.min(ret2, ret3));
}
return cache[level%2][stones] = bestChoice;
}
}
더 깔끔하게 해결할 수 있습니다. 위의 코드는 현재 턴제 기반으로 게임을 진행하고 있어서 각 턴들을 저장하고 있습니다.
하지만, return -ret; 형식처럼 마이너스 값으로 부호를 변형시켜서 반환시킴으로써 턴제 게임에서의 턴을 표현할 수 있습니다.
package Main;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
static int N, C, H, W, K, M, T;
static int answer = 0;
static int[] cache;
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
cache = new int[N+1];
Arrays.fill(cache, -2);
System.out.println(game(N) == 1 ? "SK" : "CY");
}
static int game(int N) {
//만약 마지막 돌을 가져가야할 경우 이 사람이 진것이다.
if(N == 1) {
return -1;
}
if(cache[N] != -2) return cache[N];
int ret;
ret = game(N - 1);
if(N-3 >= 1)
ret = Math.min(ret, game(N-3));
if(N-4 >= 1){
ret = Math.min(ret, game(N-4));
}
return cache[N] = -ret;
}
}
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 10025 게으른 백곰 - 슬라이딩 윈도우(Sliding Window) JAVA (0) | 2024.07.29 |
---|---|
[백준] 9659 돌 게임 5 - 동적계획법(DP, Dynamic Programming) + 게임이론(Game Theory) + 수학(Math) JAVA (0) | 2024.07.29 |
[백준] 2659 십자카드 문제 - 브루트포스(BruteForce, 완전탐색) JAVA (0) | 2024.07.28 |
[백준] 2548 대표 자연수 - 정렬(Sorting) + 수학(Math) JAVA (0) | 2024.07.28 |
[백준] 2108 통계학 - 구현(Implementation) + 정렬(Sorting) JAVA (0) | 2024.07.28 |