[백준] 9465번 : 스티커

김건우·2024년 9월 2일
0

문제 풀이

목록 보기
58/62

오랜만에 DP 문제를 풀어봤다.
확실히 DP 문제는 그림을 그려서 각 자리에서의 최대값을 어떻게 구할지 생각해보면 답이 눈에 보이는 것 같다.

여기서는 2열짜리 2차원배열로 주어지는데, 각 자리의 스티커를 뗐을 때 최대값을 구하면 된다.

계산을 쉽게 하기 위해서 0번째 자리([0,0], [1,0])는 0으로 초기화해두고,
[0,1], [1,1] 열에서의 최대값은 항상 자기자신이기에 설정해두고 시작한다.

2번째 자리 부터는 그 자리의 스티커를 떼면 이전 값들의 최대값과 비교를해서 각 자리에서 최대값을 업데이트 해줘야 한다.

처음에는 이런식으로 10에서 자리를 떼면 앞에 자리 대각선만 계산해주면 될 줄 알았는데,

이런식으로 50,50,100,60 으로 마지막에 60을 골라야 하는데, 10+40 을 선택하는 문제가 발생했다.

그래서 100을 기준으로 생각해보면

이처럼 [0,3] 자리에서는 [1,2],[1,1] 자리를 비교해서 최대값을 선택하는 방법을 사용하면 각 자리에서의 최대값을 제대로 구할 수 있다.

결과적으론 다음처럼 dp 배열이 이루어짐을 알 수 있다. 마지막에 [0,N],[1,N] 둘 중 최대값을 구해준다면 정답을 찾아낼 수 있다.

import java.io.*;
import java.util.*;

/**
 * 1 ≤ N ≤ 100,000
 * 시간 제한 1초
 * 메모리 제한 256 MB
 * ---
 *
 */

public class Main {
    public static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    public static StringBuilder sb = new StringBuilder();
    public static StringTokenizer st;
    public static int T;

    public static void main(String[] args) throws IOException {
        T = Integer.parseInt(br.readLine());

        for (int i=0; i<T; i++) {
            int N = Integer.parseInt(br.readLine());
            int[][] arr = new int[2][N+1];
            int[][] dp = new int[2][N+1];
            for (int j=0; j<2; j++) {
                st = new StringTokenizer(br.readLine(), " ");
                for (int k=1; k<=N; k++) {
                    arr[j][k] = Integer.parseInt(st.nextToken());
                }
            }

            dp[0][1] = arr[0][1];
            dp[1][1] = arr[1][1];
            for (int k=2; k<=N; k++) {
                dp[0][k] = Math.max(dp[1][k-1], dp[1][k-2]) + arr[0][k];
                dp[1][k] = Math.max(dp[0][k-1], dp[0][k-2]) + arr[1][k];
            }
            sb.append(Math.max(dp[1][N], dp[0][N])).append("\n");
        }
        System.out.print(sb);
    }
}
profile
공부 정리용

0개의 댓글