• toc {:toc}

문제 확인하기

풀이

이웃한 곳으로 이동하면서 목표 지점까지 이동하는 문제로, DFS와 DP를 섞어줘야 시간초과없이 문제를 풀이할 수 있다.

처음에는 stack을 이용해 bottom-up으로 마지막에 도착하는 횟수를 카운트하여 풀이하려 했지만, 다음의 경우에는 중복된 길을 지나는 경우가 많아질 수 있기 때문에 시간초과에 걸리게 된다.

때문에 도착지점에서 역으로 이동할 수 있는 횟수를 카운트하면서 처음 시작지점까지 도달할 수 있도록 설정하면 시작지점에서 도착지점까지 이동할 수 있는 횟수를 카운트 할 수 있다.

입력 배열 image

dist 배열 image

1인 경우에는 도착지점에서 해당 위치까지 오는 방식이 1개만 존재한다는 의미이다.

#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
 
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
int board[501][501] = {0,};
int dist[501][501];
int M, N, res = 0;
 
int dfs(int X, int Y){
    if(X == M-1 && Y == N-1){
        return 1;
    }
    if(dist[X][Y] == -1){
        dist[X][Y] = 0;
        for(int dir = 0; dir < 4; dir++){
            int nx = X + dx[dir];
            int ny = Y + dy[dir];
            if(nx < 0 || nx >= M || ny < 0 || ny >= N) continue;
            if(board[X][Y] <= board[nx][ny]) continue;
            dist[X][Y] += dfs(nx, ny);
        }
 
    }
    return dist[X][Y];
}
 
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
 
 
    cin >> M >> N;
 
    for(int row = 0; row < M; row++){
        for(int col = 0; col < N; col++){
            cin >> board[row][col];
            dist[row][col] = -1;
        }
    }
 
 
    cout << dfs(0, 0) << '\n';
 
 
    return 0;
}