https://www.acmicpc.net/problem/2169
2169번: 로봇 조종하기
첫째 줄에 N, M(1≤N, M≤1,000)이 주어진다. 다음 N개의 줄에는 M개의 수로 배열이 주어진다. 배열의 각 수는 절댓값이 100을 넘지 않는 정수이다. 이 값은 그 지역의 가치를 나타낸다.
www.acmicpc.net
저는 해당 문제를 DP를 이용하여 문제를 해결하였습니다.
해당 좌표를 오는 방향에 따라서 다르게 고려해야 하기 때문에 일반적인 DP랑 다르게 방향까지 고려하여 DP를 작성하였습니다. ( DP[y좌표][x좌표][이 좌표로 오기 전의 방향] )
또 다음 방향을 정할 때 왼쪽방향이였다면 오른쪽으로는 못 가게 오른쪽이라면 왼쪽으로는 못 가게 구현하였습니다.
package BOJ.DP;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.util.function.Function;
public class BOJ_2169 {
private static final int[] dy = {0,1,0};
private static final int[] dx = {1,0,-1};
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine()," ");
Function<String,Integer> stoi = Integer::parseInt;
int n = stoi.apply(st.nextToken());
int m = stoi.apply(st.nextToken());
int[][] map = new int[n][m];
for(int i = 0 ; i < n ; i++){
st = new StringTokenizer(br.readLine()," ");
for(int j = 0 ; j < m ; j++){
map[i][j] = stoi.apply(st.nextToken());
}
}
int[][][] dp = new int[n][m][3];
for(int i = 0 ; i < n ; i++){
for(int j = 0 ; j < m ; j++){
Arrays.fill(dp[i][j],NOT_VALID);
}
}
int result = dfs(0,0,1,map,n,m,dp);
System.out.println(result);
}
private static final int NOT_VALID = 987_654_321;
private static final int INF = 100 * 1_000 * 1_000;
private static int dfs(int y , int x,int dir, int[][] map, int n, int m, int[][][] dp) {
if(y == n-1 && x == m-1){
return map[y][x];
}
if(dp[y][x][dir] != NOT_VALID){
return dp[y][x][dir];
}
int result = -INF;
for(int nextDir = 0 ; nextDir < 3 ; nextDir++){
if( (dir == 0 || dir == 2) && (nextDir == 0 || nextDir == 2) && (dir != nextDir) ){
continue;
}
int ny = y + dy[nextDir];
int nx = x + dx[nextDir];
if(!checkBound(ny,nx,n,m)){
continue;
}
result = Math.max(result,dfs(ny,nx,nextDir,map,n,m,dp));
}
dp[y][x][dir] = result + map[y][x];
return dp[y][x][dir];
}
private static boolean checkBound(int y ,int x , int n,int m){
if(y >= 0 && y < n && x >= 0 && x < m){
return true;
}
return false;
}
}
'알고리즘' 카테고리의 다른 글
백준 16401번 과자 나눠주기 (JAVA) (0) | 2022.05.11 |
---|---|
백준 12919번 A와 B 2 (JAVA) (0) | 2022.05.10 |
백준 1240번 노드사이의 거리 (JAVA) (0) | 2022.05.08 |
프로그래머스 게임 맵 최단거리 (JAVA) (0) | 2022.05.07 |
프로그래머스 [1차] 셔틀버스 (JAVA) (0) | 2022.05.06 |