728x90
DFS와 DP를 사용하여 내리막길로 길을 가다가 만약 방문한 적이 있는 칸이 있다면 끝까지 가지 않고 해당 칸의 DP 값을 더한다.
DP는 해당 칸에서 목적지까지 갈 수 있는 경우의 수다. -1로 초기화한 이유는 0인 경우는 목적지까지 갈 수 있는 경우의 수가 없는 것이고 -1인 경우는 아직 방문을 안한 경우다.
(x, y)가 목적지면 1을 리턴하고 방문한 적이 있으면 해당 DP값을 리턴한다. 아직 방문을 하지 않았으면 상, 하, 좌, 우를 보며 지점의 높이가 더 낮으면 해당 지점으로 가서 DP값을 계산하여 이렇게 상, 하, 좌, 우의 갈 수 있는 DP값을 더해준다.
전체 코드
#include <bits/stdc++.h>
using namespace std;
int dx[] = { -1,0,1,0 };
int dy[] = { 0,-1,0,1 };
vector<vector<int>> board(501, vector<int>(501)); // 지도
vector<vector<int>> DP(501, vector<int>(501, -1)); // (i, j)에서 목적지까지의 경우의 수
int N, M, answer;
int DFS(int x, int y) {
if (x == N - 1 and y == M - 1)
return 1;
// 이미 방문한 적이 있어 경우의 수를 계산을 해놓은 경우
if (DP[x][y] > -1)
return DP[x][y];
// 경우의 수 계산
DP[x][y] = 0;
for (int k = 0; k < 4; k++) {
int xpos = x + dx[k];
int ypos = y + dy[k];
if (xpos < 0 or xpos >= N or ypos < 0 or ypos >= M)
continue;
if(board[x][y] > board[xpos][ypos])
DP[x][y] += DFS(xpos, ypos);
}
return DP[x][y];
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> N >> M;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
cin >> board[i][j];
}
}
answer = DFS(0, 0);
cout << DP[0][0];
return 0;
}
728x90
반응형
'코딩테스트 > c++' 카테고리의 다른 글
[백준] 1068번 트리 (0) | 2021.11.24 |
---|---|
[백준] 2146번 다리 만들기 (0) | 2021.11.23 |
[백준] 3584번 가장 가까운 공통 조상 (0) | 2021.11.21 |
[백준] 10026번 적록색약 (0) | 2021.11.20 |
[백준] 2206번 벽 부수고 이동하기 (0) | 2021.11.19 |