http://leetcode.com/problems/maximum-number-of-moves-in-a-grid
class Solution {
public int maxMoves(int[][] grid) {
int ans=0;
int c = grid[0].length;
int r = grid.length;
int dp[][] = new int[r][c];
for (int j = c - 2; j >= 0; j--) {
for (int i = 0; i < r; i++) {
if (i - 1 >= 0 && j + 1 < c && grid[i][j] < grid[i - 1][j + 1]) {
dp[i][j] = Math.max(dp[i][j], dp[i - 1][j + 1] + 1);
}
if (grid[i][j] < grid[i][j + 1]) {
dp[i][j] = Math.max(dp[i][j], dp[i][j + 1] + 1);
}
if (i + 1 < r && j + 1 < c && grid[i][j] < grid[i + 1][j + 1]) {
dp[i][j] = Math.max(dp[i][j], dp[i + 1][j + 1] + 1);
}
}
}
for (int k = 0; k < r; k++) {
ans = Math.max(ans, dp[k][0]);
}
return ans;
}
}
1. 문제

m*n의 배열이 주어진다. 해당 배열의 왼쪽 끝에서 시작하여 이동하는데, 우상, 우, 우하의 방향으로 현재 위치의 값보다 큰 숫자로만 이동할 수 있다. 이 때 가능한 최대 움직임 수를 구하라.
2. 풀이
DP 문제이다. 종착점은 배열에 따라 다르지만, 시작점은 항상 일정하므로 우측 끝에서부터 역으로 이동하여 풀도록 하자.
int c = grid[0].length;
int r = grid.length;
int dp[][] = new int[r][c];
우선 메모이제이션 배열을 선언한다. 정의는 다음과 같다.
- dp[i][j]: (i, j)에서 시작하여 조건에 맞춰 이동할 수 있는 최대 거리
for (int j = c - 2; j >= 0; j--) {
for (int i = 0; i < r; i++) {
if (i - 1 >= 0 && j + 1 < c && grid[i][j] < grid[i - 1][j + 1]) {
dp[i][j] = Math.max(dp[i][j], dp[i - 1][j + 1] + 1);
}
if (grid[i][j] < grid[i][j + 1]) {
dp[i][j] = Math.max(dp[i][j], dp[i][j + 1] + 1);
}
if (i + 1 < r && j + 1 < c && grid[i][j] < grid[i + 1][j + 1]) {
dp[i][j] = Math.max(dp[i][j], dp[i + 1][j + 1] + 1);
}
}
}
이후 좌측으로 가면서 계산한다. 문제의 조건을 역으로 탐색하면 좌상, 좌, 좌하로 현재 위치보다 작은 숫자의 경우에만 이동할 수 있다. 이에 따라 배열의 범위를 확인하면서 세 가지 케이스를 확인해준다.
for (int k = 0; k < r; k++) {
ans = Math.max(ans, dp[k][0]);
}
return ans;
이후 맨 좌측의 어디서 출발해야 최대 거리를 이동할 수 있는 지 확인, 그 거리를 리턴한다.
'Coding Test' 카테고리의 다른 글
| Leetcode 3163 String Compression III (Java) (0) | 2024.11.04 |
|---|---|
| Leetcode 1277 Count Square Submatrices with All Ones (Java) (1) | 2024.11.01 |
| 프로그래머스 기능개발 (Java) (1) | 2024.10.28 |
| Leetcode 921 Minimum Add to Make Parentheses Valid (Java) (1) | 2024.10.09 |
| 백준 6497 전력난 (Java) (0) | 2024.10.06 |