티스토리 뷰
내리막길은 DFS와 DP를 혼합하여 해결할 수 있는 문제이다.
DFS를 이용하여 종점을 찾아서
다시 돌아오면서 DP로 현재 경로에서 종점으로 갈 수 있는 경우를 메모한다.
이미 메모한 곳을 찾으면 해당 값을 반환하면 된다.
* -1로 초기화 하여, 방문한 곳을 0으로 표시하면 다시 방문하지 않아도 된다.
최종 위치에서 되돌아 가면서 경로를 표시하고,
새로운 경로로 가면서 최종 위치로 도달할 수 있는 경로를 만나면 그값을 더하여 처리한다.
<테스트 케이스>
10 10
20 19 18 17 16 15 14 13 12 11
19 18 17 16 15 14 13 12 11 10
18 17 16 15 14 13 12 11 10 9
17 16 15 14 13 12 11 10 9 8
16 15 14 13 12 11 10 9 8 7
15 14 13 12 11 10 9 8 7 6
14 13 12 11 10 9 8 7 6 5
13 12 11 10 9 8 7 6 5 4
12 11 10 9 8 7 6 5 4 3
11 10 9 8 7 6 5 4 3 2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package sdk.backjun.dp; | |
import java.util.Arrays; | |
import java.util.Scanner; | |
/** | |
* 백준, 1520, 내리막길 | |
* https://www.acmicpc.net/problem/1520 | |
* | |
* @author whitebeardk | |
* | |
*/ | |
public class Problem1520 { | |
static int N; | |
static int M; | |
static int[][] moves = { { 0, 1 }, { 0, -1 }, { 1, 0 }, { -1, 0 } }; | |
public static void main(String[] args) { | |
Scanner sc = new Scanner(System.in); | |
M = sc.nextInt(); | |
N = sc.nextInt(); | |
int[][] maps = new int[M][N]; | |
for (int i = 0; i < M; i++) { | |
for (int j = 0; j < N; j++) { | |
maps[i][j] = sc.nextInt(); | |
} | |
} | |
sc.close(); | |
// 방문한곳 처리를 위해 -1로 초기화 | |
int[][] dp = new int[M][N]; | |
for (int[] arr : dp) | |
Arrays.fill(arr, -1); | |
// 종료지점 확인 | |
dp[M - 1][N - 1] = 1; | |
findWay(maps, dp, 0, 0); | |
System.out.println(dp[0][0]); | |
// 경로 확인 | |
for (int i = 0; i < M; i++) { | |
for (int j = 0; j < N; j++) { | |
System.out.printf("%6d ", dp[i][j]); | |
} | |
System.out.println(); | |
} | |
} | |
public static int findWay(int[][] maps, int[][] dp, int x, int y) { | |
// 종점 도달 | |
if (x == M - 1 && y == N - 1) | |
return 1; | |
// 이미 처리한 곳 | |
if (dp[x][y] >= 1 || dp[x][y] == 0) | |
return dp[x][y]; | |
// 방문 처리 | |
if (dp[x][y] == -1) { | |
dp[x][y] = 0; | |
} | |
for (int i = 0; i < moves.length; i++) { | |
int nextX = x + moves[i][0]; | |
int nextY = y + moves[i][1]; | |
if (0 <= nextX && nextX < maps.length && 0 <= nextY && nextY < maps[0].length && maps[x][y] > maps[nextX][nextY]) { | |
dp[x][y] += findWay(maps, dp, nextX, nextY); | |
} | |
} | |
return dp[x][y]; | |
} | |
} |
반응형
'알고리즘 > 백준' 카테고리의 다른 글
[백준][다이나믹] 10844 쉬운계단수 (0) | 2017.06.21 |
---|---|
[백준][위상정렬, DAG] 2252 줄세우기 (0) | 2017.06.20 |
[백준][다이나믹] 2156 포도주 시식 (0) | 2017.06.19 |
[백준] 1003 피보나치 함수 (0) | 2017.06.01 |
[백준] 1932 숫자삼각형 (0) | 2017.05.31 |
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- HIVE
- Python
- 백준
- 하이브
- 하둡
- hbase
- HDFS
- Tez
- bash
- error
- 오류
- ubuntu
- 파이썬
- AWS
- S3
- SQL
- 정올
- yarn
- nodejs
- java
- 다이나믹
- oozie
- mysql
- emr
- 알고리즘
- Linux
- Hadoop
- SPARK
- airflow
- build
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
글 보관함