ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준 11062 - JAVA] 카드 게임
    Algorithm 2020. 11. 12. 18:32
    반응형
     

    11062번: 카드 게임

    근우와 명우는 재미있는 카드 게임을 하고 있다. N개의 카드가 일렬로 놓여 있다. 각 카드에는 점수가 적혀있다. 근우부터 시작하여 번갈아가면서 턴이 진행되는데 한 턴에는 가장 왼쪽에 있는

    www.acmicpc.net

    정말정말 DP는 풀 때마다 모르겠다!

    결국 블로그를 참고해서 어떻게 푸는지 보고 풀었다.

    최선의 전략으로 진행하는 것이기 때문에 모든 경우를 확인해야하고,
    DP를 이용해 각 턴마다 근우가 높은 점수를 얻는 경우와 명우가 낮은 점수를 얻는 경우를 저장해둔다. 

    그래서 DP배열은 [근우와 명우의 턴][시작 카드(왼쪽 끝)의 인덱스][마지막 카드(오른쪽 끝)의 인덱스]로 크기는 [2][N][N]으로 할당한다!

     

    풀이 방법

    1. DP배열의 초기값을 -1로 넣어준다.
    2. 턴은 근우부터 0, 시작은 0, 마지막은 N-1
    3. DP에 저장된 값이 없는 경우(-1)에는 근우의 턴에서는 높은 점수를 가져가는 경우를,
      명우의 턴에서는 낮은 점수를 가져가는 경우를 저장한다.
    4. DP의 초기값(-1)이 아니라 저장된 값이 있는 경우에는 저장되어있는 값을 바로 반환한다.
    5. 카드의 시작과 끝이 같은 경우에는 한장이 남은 경우로 남은 턴에 따라 근우 점수에 더하거나 0을 반환해준다 (명우가 가진 경우)
    import java.io.*;
    import java.util.*;
    
    public class Main {
    	public static int N;
    	public static int[] cards;
    	public static int[][][] dp;
    	
    	public static void main(String[] args) throws Exception {
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		StringTokenizer st;
    		
    		int T = Integer.parseInt(br.readLine());
    		for (int tc = 0; tc < T; tc++) {
    			N = Integer.parseInt(br.readLine());
    			cards = new int[N];
    			st = new StringTokenizer(br.readLine());;
    			for (int i = 0; i < N; i++) {
    				cards[i] = Integer.parseInt(st.nextToken());
    			}
    			
    			dp = new int[2][N][N];
    			for (int i = 0; i < 2; i++) {
    				for (int j = 0; j < N; j++) {
    					Arrays.fill(dp[i][j], -1);
    				}
    			}
    			System.out.println(solve(0, 0, N-1));
    		}
    	}
    	
    	public static int solve(int turn, int start, int end) {
    		if (dp[turn][start][end] != -1) {
    			return dp[turn][start][end];
    		}
    		
    		if (start == end) {
    			if (turn == 0) return cards[start];
    			else return 0;
    		}
    		
    		dp[turn][start][end] = 0;
    		if (turn == 0) {
    			dp[turn][start][end] = Math.max(solve(1, start + 1, end) + cards[start], solve(1, start, end - 1) + cards[end]);
    		} else { 
    			dp[turn][start][end] = Math.min(solve(0, start + 1, end), solve(0, start, end - 1));
    		}
    		return dp[turn][start][end];
    	}
    }
    

    'Algorithm' 카테고리의 다른 글

    [백준 3109 - JAVA] 빵집  (0) 2020.11.26
    [백준 13459 - JAVA] 구슬 탈출  (0) 2020.11.17
    [백준 4386 - JAVA] 별자리 만들기  (0) 2020.11.12
    [백준 1937 - JAVA] 욕심쟁이판다  (2) 2020.11.09
    [백준 1261 - JAVA] 알고스팟  (0) 2020.11.09

    댓글