Algorithm/Dynamic Programming
[백준] 9465. 스티커
Dev_Green
2022. 12. 4. 18:01
https://www.acmicpc.net/problem/9465
9465번: 스티커
첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스의 첫째 줄에는 n (1 ≤ n ≤ 100,000)이 주어진다. 다음 두 줄에는 n개의 정수가 주어지며, 각 정수는 그 위치에 해당하는 스티커의
www.acmicpc.net
풀이
주어진 N 값에 따라 가로의 길이가 결정되는 형태이므로 아래 코드와 같이 열을 기준으로 점화식을 세울 수 있었다.
for (int j = 2; j <= N; j++) {
dp[0][j] = Math.max(dp[1][j - 1], dp[1][j - 2]) + point[0][j];
dp[1][j] = Math.max(dp[0][j - 1], dp[0][j - 2]) + point[1][j];
}
설명하자면, dp배열에서 dp[0][j]을 계산하려면 dp[1][j - 1]과 dp[1][j - 2]를 비교하여 둘 중 큰 값을 선택한 뒤 point[0][j]을 더해주는 것이다.
처음에는
1. dp[0][j - 2] 와 dp[1][j - 2] 중 최댓값을 가려내고
2. 그 값을 또 dp[1][j - 1] 과 비교하여 최댓값을 가려낸 뒤
3. point[0][j] 를 더해준다
이런 흐름이어야 하지 않나 생각했었다.
하지만 dp[0][j - 2]를 선택했을 때 dp[0][j - 1]은 무조건 선택하게 되므로 이 경우의 계산은 dp[1][j - 1]에 반영된다.
그러므로 dp[1][j - 2]와 dp[1][j - 1]만 비교하여 dp[0][j] 값 계산에 반영하면 된다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class BOJ9465 {
static int dp[][], point[][];
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine()); // 테스트 케이스의 개수
for (int i = 0; i < T; i++) {
int N = Integer.parseInt(br.readLine()); // 스티커의 가로 길이
point = new int[2][N + 1]; // 각 위치의 포인트
dp = new int[2][N + 1]; // 각 위치까지의 최댓 점수
// 배열 입력
StringTokenizer st;
for (int j = 0; j < 2; j++) {
st = new StringTokenizer(br.readLine());
for (int k = 1; k <= N ; k++) {
point[j][k] = Integer.parseInt(st.nextToken());
}
}
// 기저 사례
dp[0][1] = point[0][1];
dp[1][1] = point[1][1];
// 현재 위치의 대각선 값과 그 왼쪽 값을 비교
for (int j = 2; j <= N; j++) {
// 점화식
dp[0][j] = Math.max(dp[1][j - 1], dp[1][j - 2]) + point[0][j];
dp[1][j] = Math.max(dp[0][j - 1], dp[0][j - 2]) + point[1][j];
}
System.out.println(Math.max(dp[0][N], dp[1][N]));
}
}
}