1520번: 내리막 길
첫째 줄에는 지도의 세로의 크기 M과 가로의 크기 N이 빈칸을 사이에 두고 주어진다. 이어 다음 M개 줄에 걸쳐 한 줄에 N개씩 위에서부터 차례로 각 지점의 높이가 빈 칸을 사이에 두고 주어진다.
www.acmicpc.net
이 문제는 낮은 정답률에 비해 쉽게 풀 수 있었다.
정답률이 낮은 이유는 아마도 동서남북 방향을 탐색하지 않고 동쪽과 남쪽만 탐색해서 오답을 받는 경우가 많기 때문일거라 생각한다.
동서남북 방향을 탐색하여 높이가 낮은 지점이 있다면 그 지점에서 (M, N)으로 가는 경로의 개수를 구하고 그 값을 누적해주면 된다.
한 지점에서 (M, N)으로 가는 경로의 개수는 항상 같기 때문에 이를 메모이제이션해주면 중복탐색을 최소화할 수 있다.
#include <iostream>
#include <cstring>
using namespace std;
int M, N, arr[501][501], memo[501][501];
int dy[4] = { 1,-1,0,0 }, dx[4] = { 0,0,1,-1 };
int Topdown(int hereY, int hereX)
{
if (hereY > M || hereY == 0 || hereX > N || hereX == 0)
return 0;
if (hereY == M && hereX == N)
return 1;
int& ret = memo[hereY][hereX];
if (ret != -1) return ret;
ret = 0;
for (int i = 0; i < 4; i++)
if (arr[hereY][hereX] > arr[hereY + dy[i]][hereX + dx[i]])
ret += Topdown(hereY + dy[i], hereX + dx[i]);
return ret;
}
int main(void)
{
cin >> M >> N;
for (int i = 1; i <= M; i++)
for (int j = 1; j <= N; j++)
cin >> arr[i][j];
memset(memo, -1, sizeof(memo));
cout << Topdown(1, 1) << endl;
return 0;
}
알고리즘 200일 프로젝트 - 88 day
'알고리즘 > BOJ' 카테고리의 다른 글
백준 1890번: 점프 (0) | 2020.07.03 |
---|---|
백준 2225번: 합분해 (0) | 2020.07.03 |
백준 11054번: 가장 긴 바이토닉 부분 수열 (0) | 2020.07.02 |
백준 11722번: 가장 긴 감소하는 부분수열 (0) | 2020.07.02 |
백준 1904번: 01타일 (0) | 2020.07.01 |