이번 문제는 깊이우선탐색과 다이나믹 프로그래밍을 이용해서 해결하였다. 처음에는 깊이우선탐색으로만 접근하였다. 단순하게 dfs() 함수에서 현재 위치보다 다음 위치가 작을 경우에 재귀호출 시키고 만약 [m-1][n-1]에 도달하면 전역변수를 1 증가시키는 방법으로 구현하였다. 테스트 케이스에 대한 정답은 잘 도출되었다.
import sys
sys.setrecursionlimit(10**9)
input = sys.stdin.readline
def dfs(y, x):
global cnt
dy=[0, 0, -1, 1]
dx=[1, -1, 0, 0]
if y==m-1 and x==n-1:
cnt+=1
return
for i in range(4):
ny=y+dy[i]
nx=x+dx[i]
if ny>=0 and nx>=0 and ny<m and nx<n and maps[ny][nx]<maps[y][x]:
dfs(ny, nx)
m, n=map(int, input().split())
maps=[]
for _ in range(m):
maps.append(list(map(int, input().split())))
cnt=0
dfs(0, 0)
print(cnt)
그러나 시간초과가 발생하였다. 질문하기를 찾아 본 결과 DFS + DP를 적용해야 시간 안에 해결할 수 있다는 사실을 알았다. 아마도 m과 n을 최댓값으로 넣었을 때에 수가 너무 커지기 때문인 것 같았다.
그래서 DFS + DP 방식으로 풀이하였다. dp리스트로 방문처리와 카운팅을 동시에 하였다. -1로 초기화를 시키고 dp[y][x]가 -1일 경우, 아직 방문하지 않은 위치로 판단하고 탐색을 진행하도록 하였고, -1이 아니라면 이전에 방문한 적이 있는 위치이므로 그 dp[y][x] 값을 더해주도록 하였다. 만약 [m-1][n-1]에 도달했다면 dp[y][x]에 1을 더해주었다.
DFS와 DP를 결합한 문제는 처음 접해보아서 많은 시간을 쏟았다. 조금은 찾아보면서 풀이하였다. 이런 문제들도 많이 풀어봐야겠다는 생각을 했다.
import sys
sys.setrecursionlimit(10**9)
input = sys.stdin.readline
def dfs(y, x):
dy=[0, 0, -1, 1]
dx=[1, -1, 0, 0]
if y==m-1 and x==n-1:
return 1
if dp[y][x]!=-1:
return dp[y][x]
dp[y][x]=0
for i in range(4):
ny=y+dy[i]
nx=x+dx[i]
if ny>=0 and nx>=0 and ny<m and nx<n and maps[ny][nx]<maps[y][x]:
dp[y][x]+=dfs(ny, nx)
return dp[y][x]
m, n=map(int, input().split())
maps=[]
for _ in range(m):
maps.append(list(map(int, input().split())))
dp=[[-1]*n for _ in range(m)]
print(dfs(0, 0))