문제 설명
https://www.acmicpc.net/problem/1937
1937번: 욕심쟁이 판다
n*n의 크기의 대나무 숲이 있다. 욕심쟁이 판다는 어떤 지역에서 대나무를 먹기 시작한다. 그리고 그 곳의 대나무를 다 먹어 치우면 상, 하, 좌, 우 중 한 곳으로 이동을 한다. 그리고 또 그곳에서
www.acmicpc.net
[문제]
n*n의 크기의 대나무 숲이 있다. 욕심쟁이 판다는 어떤 지역에서 대나무를 먹기 시작한다. 그리고 그 곳의 대나무를 다 먹어 치우면 상, 하, 좌, 우 중 한 곳으로 이동을 한다. 그리고 또 그곳에서 대나무를 먹는다. 그런데 단 조건이 있다. 이 판다는 매우 욕심이 많아서 대나무를 먹고 자리를 옮기면 그 옮긴 지역에 그 전 지역보다 대나무가 많이 있어야 한다. 만약에 그런 지점이 없으면 이 판다는 불만을 가지고 단식 투쟁을 하다가 죽게 된다(-_-)
이 판다의 사육사는 이런 판다를 대나무 숲에 풀어 놓아야 하는데, 어떤 지점에 처음에 풀어 놓아야 하고, 어떤 곳으로 이동을 시켜야 둘 다 소중한 생명이지만 판다가 최대한 오래 살 수 있는지 고민에 빠져 있다. 우리의 임무는 이 사육사를 도와주는 것이다. n*n 크기의 대나무 숲이 주어져 있을 때, 이 판다가 최대한 오래 살려면 어떤 경로를 통하여 움직여야 하는지 구하여라.
[입력]
첫째 줄에 대나무 숲의 크기 n(1 ≤ n ≤ 500)이 주어진다. 그리고 둘째 줄부터 n+1번째 줄까지 대나무 숲의 정보가 주어진다. 대나무 숲의 정보는 공백을 사이로 두고 각 지역의 대나무의 양이 정수 값으로 주어진다. 대나무의 양은 1,000,000보다 작거나 같은 자연수이다.
[출력]
첫째 줄에는 판다가 최대한 살 수 있는 일수(K)를 출력한다.
[예제 입력 1]
4
14 9 12 10
1 11 5 4
715 2 13
6 3 16 8
[예제 출력 1]
4
풀이
최근에 풀었던 내리막 길 문제와 굉장히 비슷한 문제였다. 다만 이 문제는 요소의 크기가 커지는 방향으로 가야 하고, 시작 지점이 명시가 되어있지 않았기 때문에 배열의 전 지점에 대해서 함수를 실행할 필요가 있었다.
또한 이 문제도 핵심은 함수 호출 횟수를 줄이는 것이기 때문에, 캐시 배열을 만들고 이를 통해 기존 값이 존재하면 해당 값을 반환하여 함수 호출을 줄이는 것으로 코드를 작성했다.
#include <iostream>
#include <vector>
using namespace std;
vector<vector<int>> cache;
int searchRoute(int n, vector<vector<int>>& map, int r, int c, int prev) {
int result = 0;
if (r < 0 || r >= n || c < 0 || c >= n) //인덱스 범위 밖
return 0;
if (map[r][c] <= prev) //이전 높이보다 작거나 같은 경우
return 0;
if (cache[r][c] != -1) //한 번도 가본 길이 아닌 경우 캐시 반환
return cache[r][c];
//상하좌우 길 탐색
result = max(result, searchRoute(n, map, r, c + 1, map[r][c]));
result = max(result, searchRoute(n, map, r + 1, c, map[r][c]));
result = max(result, searchRoute(n, map, r, c - 1, map[r][c]));
result = max(result, searchRoute(n, map, r - 1, c, map[r][c]));
return cache[r][c] = result + 1;//저장한 캐시 반환
}
int main() {
int n;
int answer = 0;
vector<vector<int>> map;
cin >> n;
for (int i = 0; i < n; i++) {//캐시 벡터, 맵 벡터 초기화
vector<int> temp(n, 0);
vector<int> temp2(n, -1);
for (int j = 0; j < n; j++)
cin >> temp[j];
map.push_back(temp);
cache.push_back(temp2);
}
for (int i = 0; i < n; i++) {//모든 지점에 대해 탐색 진행
for (int j = 0; j < n; j++) {
if (cache[i][j] == -1)
answer = max(answer, searchRoute(n, map, i, j, 0));
else
answer = max(answer, cache[i][j]);
}
}
cout << answer;
return 0;
}
결과

'Algorithm > 코드 풀이' 카테고리의 다른 글
| 1915번: 가장 큰 정사각형 (0) | 2021.04.10 |
|---|---|
| 1916번: 최소비용 구하기 (0) | 2021.04.10 |
| 1753번: 최단경로 (0) | 2021.04.02 |
| 2225번: 합분해 (0) | 2021.03.21 |
| 1005번: ACM Craft (0) | 2021.03.21 |