문제링크 : https://www.acmicpc.net/problem/21923
21923번: 곡예 비행
동헌이는 모형 비행기 조종 대회에 참가하였다. 이 대회에서는 격자 모양의 공간에서 모형 비행기를 조종하여 얻는 비행 점수로 순위를 매긴다. 격자의 각 칸에는 점수가 부여되어 있고, 비행
www.acmicpc.net
접근 과정 :
- 상승 비행과 하강 비행을 따로 관리 (상승 구간과 하강 구간이 중복되는 칸이 1~N개 있다!!!)
- 상승 비행이 끝나는 칸 == 하강 비행이 시작하는 칸
- 비행 점수 = (r,c)까지 상승한 경우 + (r,c)부터 하강하는 경우
- DP로 하강 비행을 탐색하고 하강 비행 탐색 로직 내부에서 상승 비행 탐색을 수행
- 하강비행 = (r,c)까지 상승비행 + (r,c)부터 하강비행 OR (r-1,c)부터 하강비행 OR (r,c-1)부터 하강비행
소스 코드 및 결과 :
package BOJ;
/*
곡예 비행
1. 해당 좌표까지 상승으로 얻을 수 있는 최대 값
2. + 해당 좌표부터 하강으로 얻을 수 있는 최대 값
*/
import java.io.*;
import java.util.*;
public class BOJ21923 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
board = new int[N][M];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < M; j++) {
board[i][j] = Integer.parseInt(st.nextToken());
}
}
upDP = new int[N][M];
downDP = new int[N][M];
upVisit = new boolean[N][M];
downVisit = new boolean[N][M];
int max = findDown(N-1, M-1);
System.out.println(max);
}
static int N, M;
static int[][] board;
static int INF = -40000000;
static int[][] upDP;
static int[][] downDP;
static boolean[][] upVisit;
static boolean[][] downVisit;
static int findUP(int r, int c) {
if (upVisit[r][c]) {
return upDP[r][c];
}
upVisit[r][c] = true;
if (r == N - 1 && c == 0) {
return upDP[r][c] = board[N - 1][0];
}
if (r == N - 1) {
return upDP[r][c] = findUP(r, c - 1) + board[r][c];
}
if (c == 0) {
return upDP[r][c] = findUP(r + 1, c) + board[r][c];
}
return upDP[r][c] = Math.max(findUP(r + 1, c), findUP(r, c - 1)) + board[r][c];
}
static int findDown(int r, int c) {
if (downVisit[r][c]) {
return downDP[r][c];
}
downVisit[r][c] = true;
if (r == 0 && c == 0) {
return downDP[r][c] = findUP(0,0)+board[0][0];
}
if (r == 0) {
return downDP[r][c] = Math.max(findUP(r, c), findDown(r, c - 1)) + board[r][c];
}
if (c == 0) {
return downDP[r][c] = Math.max(findUP(r, c), findDown(r - 1, c)) + board[r][c];
}
return downDP[r][c] = Math.max(findUP(r, c), Math.max(findDown(r - 1, c), findDown(r, c - 1))) + board[r][c];
}
}
P.S
범위에 대한 부분을 좀 더 깔끔하게 정리할 수 있지 않을까....
'Algorithm' 카테고리의 다른 글
[백준 Platinum 5] 3197 백조의 호수 - Java (0) | 2021.12.17 |
---|---|
[백준 Silver 3] 15270 친구 팰린드롬 - Java (0) | 2021.12.16 |
[백준 Gold 4] 14499 주사위 굴리기 - Java (0) | 2021.12.16 |
[백준 Silver 2] 11722 가장 긴 감소하는 부분 수열 - Java (0) | 2021.12.16 |
[백준 Silver 1] 2583 영역구하기 - Java (0) | 2021.12.16 |