알고리즘
[C++] 백준 1520번 내리막 길
J3SUNG
2019. 6. 4. 01:21
728x90
다이나믹 프로그래밍 문제입니다.
DFS나 BFS로만 풀게되면 시간초과가 발생합니다.
N * M 크기의 배열에서 숫자가 작아지는 길로만 이동해서
(0, 0) 에서 (N, M)의 위치까지 갈 수 있는 경우의 수를 찾는 문제입니다.
DFS방식으로 접근을 하고 (N, M)의 위치에 도착하면 성공한 경로의 memo값에 1을 더해줍니다.
다시 접근할 때 성공한 경로의 위치 중 한군데에 접근을 하면
성공한 경로의 memo값을 통해서 현재 경로의 값에도 값을 추가해줍니다.
이와 같은 방식으로 DFS와 DP를 통해 문제를 해결했습니다.
#include <iostream>
#include <cstring>
using namespace std;
int map[510][510];
int memo[510][510];
int moveX[4] = { 0, 1, 0, -1 };
int moveY[4] = { 1, 0, -1, 0 };
int M, N;
int search(int i, int j)
{
if (i == M && j == N) {
return 1;
}
int &result = memo[i][j];
if (result != -1) {
return result;
}
result = 0;
for (int k = 0; k < 4; ++k) {
int x = i + moveX[k];
int y = j + moveY[k];
if (map[x][y] < map[i][j] && x > 0 && x <= M && y > 0 && y <= N) {
result += search(x, y);
}
}
return result;
}
int main(void)
{
cin >> M >> N;
for (int i = 1; i <= M; i++) {
for (int j = 1; j <= N; j++) {
cin >> map[i][j];
}
}
memset(memo, -1, sizeof(memo));
cout << search(1, 1) << endl;
return 0;
}