문제 확인
dfs 커팅, 완전 탐색으로 풀 수 있지만 500x500 이므로 크기가 커서 효율성이 떨어지기 때문에 dfs, dp로 풀어야 합니다.
풀이
판다는 전 지역보다 옮긴 지역이 더 많은 대나무가 있어야 하므로 다음식을 항상 만족합니다.
ary[ path[i][x] ][ path[i][y] ] < ary[ path[i + 1][x] ][ path[i + 1][y] ]
따라서 dfs 탐색 도중 왔던 길을 다시 갈 수 없기 때문에 visited를 사용하지 않아도 됩니다.
dp[x][y] : 현재 위치에서 갈 수 있는 최대 depth로 두고 문제를 풉니다.
배열 범위를 나가지 않는 선에서 다음 식을 통해 dp를 완성할 수 있습니다.
for( 상, 하, 좌, 우)
if(ary[x][y] < ary[next x][next y])
dp[x][y] = max(dp[x][y], dfs(next x, next y);
dp[x][y]++;
코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
#include <iostream>
#include <algorithm>
using namespace std;
int n, ary[500][500], dp[500][500];
int dx[] = { 0, 0, 1, -1 },
dy[] = { 1, -1, 0, 0 };
int dfs(int x, int y) {
int &cur = dp[x][y];
if (cur) return cur;
for (int d = 0; d < 4; d++) {
if (x + dx[d] < 0 || n <= x + dx[d] || y + dy[d] < 0 || n <= y + dy[d]) continue;
if (ary[x][y] < ary[x + dx[d]][y + dy[d]])
cur = max(cur, dfs(x + dx[d], y + dy[d]));
}
return ++cur;
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> n;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
cin >> ary[i][j];
int mx = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
if (!dp[i][j])
mx = max(mx, dfs(i, j));
cout << mx;
}
|
cs |
반응형
'알고리즘 문제 > [백준]' 카테고리의 다른 글
[백준] 9020 골드바흐의 추측 (0) | 2021.03.04 |
---|---|
[백준] 1662 압축 (0) | 2021.03.04 |
[백준] 1786 찾기 (0) | 2021.03.02 |
[백준] 1298 노트북의 주인을 찾아서 (0) | 2021.02.22 |
[백준] 14245 XOR (0) | 2021.02.22 |