Algorithm & PS/Problem Solving
백준 - 2096. 내려가기
Dlise
2024. 3. 25. 15:30
가장 일반적인 DP 문제라고 생각해서 정리해보고자 한다.
2096. 내려가기
https://www.acmicpc.net/problem/2096
2096번: 내려가기
첫째 줄에 N(1 ≤ N ≤ 100,000)이 주어진다. 다음 N개의 줄에는 숫자가 세 개씩 주어진다. 숫자는 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 중의 하나가 된다.
www.acmicpc.net
입출력
설명
첫째 줄에 N의 크기가 주어지고 이후 N개의 줄에 0 ~ 9까지의 숫자가 3개씩 주어진다.
예제 입력의 경우 배열의 모습은 아래와 같다.
우리는 규칙에 맞게 첫째 줄부터 아래로 내려가면서 얻을 수 있는 최소 점수와 최대 점수를 구해야 한다.
(규칙: 다음 줄로 내려갈 때에는 바로 아래 수 or 아래 수와 붙어 있는 수로만 이동할 수 있다.)
접근
최소 점수와 최대 점수를 구해야 하므로 최소 점수를 구하는 배열, 최대 점수를 구하는 배열을 따로 정의해 접근했다.
최소 점수를 구하는 방법은 아래와 같다.
1. 1 번째 줄을 입력받아 값을 저장한다.
2. n 번째 줄을 입력받는 경우, 접근할 수 있는 n-1 번째 줄의 점수 중에서 작은 점수와 더한다.
만약 n == 2라면 동작 결과는 아래와 같다.
3. 마지막 줄까지 점수를 구한 후 마지막 줄 중에서 가장 작은 점수를 찾는다.
해당 예제의 경우 가장 작은 점수는 6이다.
최대 점수는 위의 동작을 최대 점수를 찾는 것으로만 바꾸면 된다.
풀이 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int N = Integer.parseInt(br.readLine());
int[][] minDp = new int[N][3];
int[][] maxDp = new int[N][3];
StringTokenizer st = new StringTokenizer(br.readLine());
int n0 = Integer.parseInt(st.nextToken());
int n1 = Integer.parseInt(st.nextToken());
int n2 = Integer.parseInt(st.nextToken());
minDp[0][0] = maxDp[0][0] = n0;
minDp[0][1] = maxDp[0][1] = n1;
minDp[0][2] = maxDp[0][2] = n2;
for (int i = 1; i < N; i++) {
st = new StringTokenizer(br.readLine());
n0 = Integer.parseInt(st.nextToken());
n1 = Integer.parseInt(st.nextToken());
n2 = Integer.parseInt(st.nextToken());
minDp[i][0] = Math.min(minDp[i-1][0], minDp[i-1][1]) + n0;
maxDp[i][0] = Math.max(maxDp[i-1][0], maxDp[i-1][1]) + n0;
minDp[i][1] = Math.min(minDp[i-1][0], Math.min(minDp[i-1][1], minDp[i-1][2])) + n1;
maxDp[i][1] = Math.max(maxDp[i-1][0], Math.max(maxDp[i-1][1], maxDp[i-1][2])) + n1;
minDp[i][2] = Math.min(minDp[i-1][1], minDp[i-1][2]) + n2;
maxDp[i][2] = Math.max(maxDp[i-1][1], maxDp[i-1][2]) + n2;
}
sb.append(Math.max(maxDp[N-1][0], Math.max(maxDp[N-1][1], maxDp[N-1][2])));
sb.append("\n");
sb.append(Math.min(minDp[N-1][0], Math.min(minDp[N-1][1], minDp[N-1][2])));
System.out.println(sb);
}
}