알고리즘
백준 - 11909 배열 탈출(Java)
ksb-dev
2022. 9. 13. 16:27
https://www.acmicpc.net/problem/11909
11909번: 배열 탈출
상수는 2차원 배열 A[1..n][1..n] (n≥2, n은 자연수)을 가지고 있습니다. 이 배열의 각 원소는 1 이상 222 이하의 정수입니다. 배열을 가지고 놀던 상수를 본 승현이는, 질투심이 불타올라 상수를 A[1][1]
www.acmicpc.net
DP 문제입니다.
N이 주어졌을 때, 2차원 배열 (1, 1)에서 특정 조건을 따르면서 (N, N)까지 가는 최소 경로를 구하는 문제입니다.
문제 조건은 백준 문제에 잘 적혀있으니 추가적인 설명은 하지 않겠습니다.
(문제 아래에 힌트가 있으니 문제가 이해가지 않으면 참고하시기 바랍니다.)
단, 주의해야 할 점은 현재 숫자가 이동 하려는 위치의 숫자보다 커야합니다.
(동일하면 움직일 수 없기 때문에 현재 숫자를 증가시켜야 합니다.)
반복문 두 개를 겹쳐 가로, 세로로 이동할 수 있는 위치를 판단해 이동시켰을 때의 최소를 갱신시키면 됩니다.
최소 갱신은 dp 배열에 저장합니다.
[구현 코드]
import java.io.*;
import java.util.StringTokenizer;
public class Main {
private static int n;
private static int[][] map, dp;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer stz;
n = Integer.parseInt(br.readLine());
map = new int[n + 1][n + 1];
dp = new int[n + 1][n + 1];
for (int i = 1; i < n + 1; i++) {
stz = new StringTokenizer(br.readLine(), " ");
for (int j = 1; j < n + 1; j++) {
map[i][j] = Integer.parseInt(stz.nextToken());
}
}
dp[1][1] = 0;
for (int i = 1; i < n+1; i++) {
for (int j = 1; j < n+1; j++) {
if (i == 1 && j == 1) continue;
// 가로 위치 판단
int c = map[i][j] - map[i][j - 1];
// 세로 위치 판단
int r = map[i][j] - map[i - 1][j];
int a = 0;
int b = 0;
// 가로 비교
if (map[i][j] < map[i][j - 1]) {
// 현재가 숫자가 더 크기 때문에 숫자 증강이 필요 없음
a = dp[i][j - 1];
} else {
// 현재 숫자가 더 작기 때문에 "차이+1" 만큼 숫자 증강
a = c + 1 + dp[i][j - 1];
}
// 세로 비교
// 가로와 동일
if (map[i][j] < map[i - 1][j]) {
b = dp[i - 1][j];
} else {
b = r + 1 + dp[i - 1][j];
}
// 알고리즘상 배열 1번부터 시작하기 때문에 0번과 비교하지 않게 함
// 배열 0번을 무한대로 초기화하면 이 코드는 필요 없음
if(i == 1) b = 1_000_000;
if(j == 1) a = 1_000_000;
// 가로와 세로의 이동을 판단하여 최소의 값만 갱신함
dp[i][j] = Math.min(a, b);
}
}
bw.write(String.valueOf(dp[n][n]));
bw.flush();
bw.close();
br.close();
}
}