백준/DP 다이나믹 프로그래밍
11048 이동하기
have a good time
2022. 5. 17. 22:55
1. 풀이
문제 예시 1로 설명하겠다.
3 4
1 2 3 4
0 0 0 5
9 8 7 6
map 배열에 각 위치의 사탕 개수를 입력한다.
즉,
1 2 3 4
0 0 0 5
9 8 7 6
이 값들을 map 배열에 입력한다.
문제에서 한 점은 1) 오른쪽, 2) 아래쪽, 3) 오른쪽 아래로 이동 가능하다고 했다.
즉, (1,1) 위치에서 이동 가능한 곳은 아래 그림과 같다.

그렇기 때문에 위치(2,2)에 있는 준규가 가질 수 있는 사탕 개수의 최댓값은
(2,2) 위치의 사탕 개수 + (1,1), (1,2), (2,1) 위치 사탕 개수 중 제일 큰 값이다.
자세히 설명하자면,
(1,1) 에서 오른쪽, 아래쪽, 오른쪽 아래 방향으로 이동 가능하다. 그런데 이것은 출발지 -> 도착지 방향이다.
그렇다면 도착지에서 출발지를 바라보는 방향은 이와 반대로 왼쪽, 위쪽, 왼쪽 위 방향이 된다.
그래서 (2,2) 로 오기 전의 위치는 (2,1), (1,2), (1,1) 이다.
이를 이용해서 최대 사탕 개수를 구하려면 아래와 같은 식을 사용하면 된다.
dp[i][j] = map[i][j] + Math.max(Math.max(dp[i-1][j-1], dp[i-1][j]) , dp[i][j-1])
2. 최종 코드
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));
StringTokenizer st = new StringTokenizer(br.readLine(), " " );
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int map[][] = new int[N+1][M+1];
int dp[][] = new int[N+1][M+1];
for(int i= 1; i<=N; i++) {
st = new StringTokenizer(br.readLine(), " " );
for(int j=1; j<=M; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
for(int i=1; i<=N; i++) {
for(int j =1; j<=M;j++ ) {
dp[i][j] = map[i][j] + Math.max(Math.max(dp[i-1][j-1], dp[i-1][j]) , dp[i][j-1]);
}
}
System.out.println(dp[N][M]);
}
}