[Gold V] 내려가기 - 2096
성능 요약
메모리: 52152 KB, 시간: 332 ms
분류
다이나믹 프로그래밍, 슬라이딩 윈도우
제출 일자
2024년 11월 19일 17:20:21
문제 설명
N줄에 0 이상 9 이하의 숫자가 세 개씩 적혀 있다. 내려가기 게임을 하고 있는데, 이 게임은 첫 줄에서 시작해서 마지막 줄에서 끝나게 되는 놀이이다.
먼저 처음에 적혀 있는 세 개의 숫자 중에서 하나를 골라서 시작하게 된다. 그리고 다음 줄로 내려가는데, 다음 줄로 내려갈 때에는 다음과 같은 제약 조건이 있다. 바로 아래의 수로 넘어가거나, 아니면 바로 아래의 수와 붙어 있는 수로만 이동할 수 있다는 것이다. 이 제약 조건을 그림으로 나타내어 보면 다음과 같다.
별표는 현재 위치이고, 그 아랫 줄의 파란 동그라미는 원룡이가 다음 줄로 내려갈 수 있는 위치이며, 빨간 가위표는 원룡이가 내려갈 수 없는 위치가 된다. 숫자표가 주어져 있을 때, 얻을 수 있는 최대 점수, 최소 점수를 구하는 프로그램을 작성하시오. 점수는 원룡이가 위치한 곳의 수의 합이다.
입력
첫째 줄에 N(1 ≤ N ≤ 100,000)이 주어진다. 다음 N개의 줄에는 숫자가 세 개씩 주어진다. 숫자는 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 중의 하나가 된다.
출력
첫째 줄에 얻을 수 있는 최대 점수와 최소 점수를 띄어서 출력한다.
- 마지막 행을 기준으로 첫번째 열에 (N, 0) 올수있는 가장 큰 수
- (N, 0)으로 인접할 수 있는 좌표 -> (N-1, 0), (N-1, 1)
- 이전합이 가장 큰 수를 찾아서 map(N, 0) 과 더하면 최댓값
- 이전합이 가장 큰 수 Math.max( dp[N-1][0], dp[N-1][1] )
- 이전합이 가장 작은 수를 찾아서 map(N, 0)과 더하면 최솟값
- 이전합이 가장 작은 수 Math.min( dp[N-1][0], dp[N-1][1] )
- 1열 2열 3열에 아래로 동일한 과정을 반복하여 최댓값과 최솟값을 도출해내자
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
int[][] map = new int[N][3];
int[][][] dp = new int[2][N][3]; // [0][i][j] = max [1][i][j] = min
StringTokenizer st;
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
map[i][0] = Integer.parseInt(st.nextToken());
map[i][1] = Integer.parseInt(st.nextToken());
map[i][2] = Integer.parseInt(st.nextToken());
}
dp[0][0][0] = map[0][0];
dp[0][0][1] = map[0][1];
dp[0][0][2] = map[0][2];
dp[1][0][0] = map[0][0];
dp[1][0][1] = map[0][1];
dp[1][0][2] = map[0][2];
for (int i = 1; i < N; i++) {
dp[0][i][0] = Math.max(dp[0][i-1][0], dp[0][i-1][1]) + map[i][0];
dp[0][i][1] = Math.max(dp[0][i-1][0], Math.max(dp[0][i-1][1], dp[0][i-1][2])) + map[i][1];
dp[0][i][2] = Math.max(dp[0][i-1][1], dp[0][i-1][2]) + map[i][2];
dp[1][i][0] = Math.min(dp[1][i-1][0], dp[1][i-1][1]) + map[i][0];
dp[1][i][1] = Math.min(dp[1][i-1][0], Math.min(dp[1][i-1][1], dp[1][i-1][2])) + map[i][1];
dp[1][i][2] = Math.min(dp[1][i-1][1], dp[1][i-1][2]) + map[i][2];
}
StringBuilder sb = new StringBuilder();
sb.append(Arrays.stream(dp[0][N-1]).max().getAsInt())
.append(" ")
.append(Arrays.stream(dp[1][N-1]).min().getAsInt());
System.out.println(sb);
}
}
'코딩테스트 > 백준' 카테고리의 다른 글
[Gold III] 파티 - 1238 (1) | 2024.11.22 |
---|---|
[Gold IV] 특정한 최단 경로 - 1504 (0) | 2024.11.21 |
[Gold IV] 서강그라운드 - 14938 (0) | 2024.11.19 |
[Gold IV] 최단경로 - 1753 (0) | 2024.11.18 |
[Silver I] 숨바꼭질 - 1697 (1) | 2024.11.17 |