package source_code;
import java.util.Scanner;
// 최소 연료 사용
// 왼, 정면, 우 이동 가능
public class B_17484_JinwooMoonTrip {
static int[] dx = { -1, 0, 1 };
static int N = 0;
static int M = 0;
static int result = Integer.MAX_VALUE;
static int[][] space;
public static void main(String[] args) {
// 입력 받기
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
M = sc.nextInt();
space = new int[N][M];
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
space[i][j] = sc.nextInt();
}
}
// DFS 깊이 탐색 실시
for (int j = 0; j < M; j++) {
dfs(0, j, space[0][j], -1);
}
System.out.println(result);
}
private static void dfs(int y, int x, int sum, int prevDir) {
if (y == N - 1) {
result = Math.min(result, sum);
return;
}
for (int dir = 0; dir < 3; dir++) {
if (dir == prevDir)
continue; // 같은 방향 연속 불가능
int ny = y + 1;
int nx = x + dx[dir];
if (nx < 0 || nx >= M)
continue;
dfs(ny, nx, sum + space[ny][nx], dir);
}
}
}
정말 오랜만에 푼 DFS..
지구와 달 사이는 N x M 크기의 연료 맵으로 구성
진우는 가능한 한 연료를 적게 소모해서 달에 도착해야 함
단, 연속해서 같은 방향으로 이동 불가능
이 문제는 한 칸씩 내려가면서 세 방향 중 하나를 선택해야 하므로, 모든 경로를 완전 탐색하는 방식이 적합.
-> 이럴 때 사용하는 탐색이 DFS(깊이 우선 탐색)
private static void dfs(int y, int x, int sum, int prevDir)
for (int j = 0; j < M; j++) {
dfs(0, j, space[0][j], -1); // 첫 행 모든 열에서 출발 가능
}
if (y == N - 1) {
result = Math.min(result, sum); // 마지막 행에 도착하면 최소값 갱신
return;
}
for (int dir = 0; dir < 3; dir++) {
if (dir == prevDir) continue; // 같은 방향 연속 이동 금지
int ny = y + 1;
int nx = x + dx[dir];
if (nx < 0 || nx >= M) continue; // 범위 밖이면 스킵
dfs(ny, nx, sum + space[ny][nx], dir);
}
알고리즘은 역시 계속 풀어야한다. 안푸니까 까먹어서 이 문제 푸는데 너무 어려웠다..
DFS 문제를 기초부터 여러 개 풀면서 다시 감을 되찾을 예정이다.
알고리즘은 왜 풀어도 풀어도 어려울까!
면접 주간을 맞이하여 소홀했던 연습 패턴을 다시 얼른 되찾아야겠다. 열심히 단련하자..!