본문 바로가기

백준 - 내리막 길(1520) 본문

알고리즘

백준 - 내리막 길(1520)

Seongjun_You 2024. 3. 8. 21:18

https://www.acmicpc.net/problem/1520

 

1520번: 내리막 길

여행을 떠난 세준이는 지도를 하나 구하였다. 이 지도는 아래 그림과 같이 직사각형 모양이며 여러 칸으로 나뉘어져 있다. 한 칸은 한 지점을 나타내는데 각 칸에는 그 지점의 높이가 쓰여 있으

www.acmicpc.net

 

DFS + 메모이제이션

 

DFS를 응용해서 

중복된 길에 대한 데이터 처리 기법이다.

다음 이동할 지점이 이미 목적지에 도달할 수 있다는 데이터를 가지고 있으면

굳이 목적지까지 갈 필요가 없다.

 

ex)

 

50 45 37 32 30

49 48 90 20 25

90 90 25 17 28

27 24 22 15 10

 

dp

-1 -1 -1 -1 -1

-1 -1 -1 -1 -1

-1 -1 -1 -1 -1

-1 -1 -1 -1 -1

 

예제를 수정해서 과정을 지켜본다.

dp는 전부 -1로 초기화하고

현재 지점은 dp를 0으로 바꿔준다.

 

DFS를 진행하고 나면

0   0   0  0  0

-1 -1 -1  0  0

-1 -1 -1  0 -1

-1 -1 -1  0 -1

 

목적지는 0으로 바꾸지 않는다.

다시 되돌아갈 때 이동했던 곳의 DP값을 더해주며 이동한다.

0    0   0   -1  -1

-1  -1  -1  -1  -1

-1  -1  -1  -1  -1

-1  -1  -1  -1  -1

 

32까지 되돌아오게 되면

그 아래 20에 갈 수 있었다.

DFS 계속 진행

 

 

0   0   0   -1   -1

-1  -1  -1  0   -1

-1  -1  -1  0   -1

-1  -1  -1  0   -1

 

되돌아오는 과정에서 똑같이 반복한다.

-2  -2  -2  -2  -1

-1  -1  -1  -1  -1

-1  -1  -1  -1  -1

-1  -1  -1  -1  -1

 

-2값을 보면 50, 45, 37, 20이며

해당 부분을 이동 과정 중에 만나면

더 이상 DFS를 진행할 필요 없이 dp를 더해주며 되돌아가면 된다.

 

-2  -2  -2  -2  -1

0    0   -1  -1  -1

-1  -1  -1  -1  -1

-1  -1  -1  -1  -1

 

-4  -2  -2  -2  -1

-2  -2  -1  -1  -1

-1  -1  -1  -1  -1

-1  -1  -1  -1  -1

 

그래서 4라는 개수가 나온다.

 

 

 

#include <iostream>
#include <vector>

using namespace std;
vector<vector<int>> graph;
vector<vector<int>> visited;
void dfs(int y, int x);
int y_next[4] = { 0, -1, 0, 1 };
int x_next[4] = { 1, 0, -1, 0 };
int n, m;

void dfs(int y, int x) {
	
	if (y == n-1 && x == m-1) 
		return;
	
	if (visited[y][x] != -1)
		return;

	visited[y][x] = 0;

	for (int i = 0; i < 4; i++) {
		int cur_y = y + y_next[i];
		int cur_x = x + x_next[i];
		
		if (cur_y < 0 || cur_y >= n || cur_x < 0 || cur_x >= m)
			continue;
		
		if (graph[cur_y][cur_x] < graph[y][x])
		{
			if (visited[cur_y][cur_x] != -1) {
				visited[y][x] += visited[cur_y][cur_x];
			}
			else {
				dfs(cur_y, cur_x);
				visited[y][x] += visited[cur_y][cur_x];
			}
		}
	}

}
int main() {
	
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		vector<int> temp_vec;
		vector<int> visited_temp(m, -1);
		for (int j = 0; j < m; j++) {
			int temp;
			cin >> temp;
			temp_vec.push_back(temp);
		}
		visited.push_back(visited_temp);
		graph.push_back(temp_vec);
	}
	dfs(0, 0);
	
	cout << visited[0][0] * -1;

}

 

 

'알고리즘' 카테고리의 다른 글

백준 - Sudoku(2239)  (0) 2024.04.04
백준 - 파일 합치기(11066)  (0) 2024.03.12
백준 - LCS 2(9252)  (0) 2024.02.20
LeetCode - Number of Subarrays That Match a Pattern II  (0) 2024.02.15
백준 - 소수의 연속합(1644)  (1) 2024.02.09
Comments