728x90
반응형
SMALL
백준 문제 풀이: 17485 [진우의 달 여행 (Large)]
문제 링크: https://www.acmicpc.net/problem/17484
문제 설명:
우주선이 지구에서 출발하여 달에 도착할 때까지 연료 소비량이 최소가 되도록 경로를 선택하는 문제입니다.
이동 규칙은 다음과 같습니다:
- 각 행에서는 좌하단(↙), 아래(↓), 우하단(↘)으로만 이동할 수 있습니다.
- 연속해서 같은 방향으로 이동할 수 없습니다.
목표는 (0, x) 위치에서 출발하여 (n-1, y)에 도착하는 최소 연료 소비량을 구하는 것입니다.
문제 해결 코드
#include <iostream>
#define INF 1e9
using namespace std;
int arr[1001][1001]; // 각 위치의 연료 소비량
int dp[3][1001][1001]; // 각 방향별 최소 연료 소비량 저장
int dx[3] = { 1, 1, 1 }; // 아래 방향 이동
int dy[3] = { -1, 0, 1 }; // 좌, 아래, 우 이동 방향
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
int n, m;
cin >> n >> m;
// 입력 및 DP 배열 초기화
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> arr[i][j];
for (int h = 0; h < 3; h++) {
dp[h][i][j] = INF; // 초기값 설정 (최대값)
}
if (i == 0) { // 첫 번째 행 초기화 (시작점)
dp[0][i][j] = arr[i][j];
dp[1][i][j] = arr[i][j];
dp[2][i][j] = arr[i][j];
}
}
}
int minAns = INF;
// DP 계산
for (int i = 0; i < n - 1; i++) { // 각 행 탐색
for (int j = 0; j < m; j++) { // 각 열 탐색
for (int h = 0; h < 3; h++) { // 이동 방향 선택 (좌, 아래, 우)
int nx = i + dx[h];
int ny = j + dy[h];
if (nx < 0 || ny < 0 || nx >= n || ny >= m) continue; // 범위 초과 방지
int minFuel;
if (h == 0) { // 왼쪽에서 내려오는 경우
minFuel = min(dp[1][i][j], dp[2][i][j]);
}
else if (h == 1) { // 정면에서 내려오는 경우
minFuel = min(dp[0][i][j], dp[2][i][j]);
}
else { // 오른쪽에서 내려오는 경우
minFuel = min(dp[0][i][j], dp[1][i][j]);
}
dp[h][nx][ny] = min(dp[h][nx][ny], minFuel + arr[nx][ny]); // 최소 연료 소비량 갱신
if (i == n - 2) // 마지막 행까지 도달한 경우 최소값 갱신
minAns = min(minAns, dp[h][nx][ny]);
}
}
}
cout << minAns << '\n'; // 최솟값 출력
}
예제 입력:
3 4
1 2 3 4
5 6 7 8
9 10 11 12
예제 출력:
16
코드 설명
- 핵심 알고리즘: DP(동적 계획법)을 활용하여 연료 소비량을 최적화합니다.
- 구현 세부사항:
- 각 칸에서 좌하단(↙), 아래(↓), 우하단(↘) 방향으로만 이동 가능합니다.
- 연속으로 같은 방향으로 이동할 수 없도록 방향별 최소 연료 소비량을 저장합니다.
- 현재 칸에 도달하기 위한 최소 연료 값을 DP 배열에 저장하며 최적의 경로를 탐색합니다.
- 시간 복잡도: O(N×M), 모든 칸을 한 번씩 탐색하여 최소 연료 소비량을 계산
결과
입력된 연료 소비량을 기준으로 최적의 이동 경로를 계산하여 최소 연료 값을 출력합니다. DP 및 최적화 기법을 연습하기 좋은 문제입니다. 추가적인 질문이나 개선 사항이 있다면 댓글로 알려주세요!
728x90
반응형
LIST
'BAEKJOON > 다이나믹 프로그래밍' 카테고리의 다른 글
백준 16287번 [Parcel](C++) -yes6686- 티스토리 (0) | 2025.02.18 |
---|---|
백준 1520번 [내리막 길](C++) -yes6686- 티스토리 (1) | 2025.02.06 |
백준 10942번 [팰린드롬?](C++) -yes6686- 티스토리 (0) | 2025.01.04 |
백준 9252번 [LCS 2](C++) -yes6686- 티스토리 (0) | 2025.01.04 |
백준 7579번 [앱](C++) -yes6686- 티스토리 (0) | 2025.01.04 |