[문제 링크]

 

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

+ Recent posts