Notice
Recent Posts
Recent Comments
«   2024/11   »
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
Tags
more
Archives
Today
Total
관리 메뉴

No Limitation

[DFS/DP] MAP 형태에서 DFS와 DP를 활용한 대표예제 본문

프로그래밍

[DFS/DP] MAP 형태에서 DFS와 DP를 활용한 대표예제

yesungcho 2024. 3. 17. 13:21

전에 풀었던 유형이지만 코테를 대비해서 체화하기 위해 문제를 다시 풀어보았다. 

2X2 그리드로 주어지는 MAP 형태에서 DFS, DP를 사용하는 경우 보통 "~한 경우의 수"를 구하는 문제에서 주로 출제된다.

즉, count+=1를 종점에 도착했을 때마다 더해주어 이를 누적하는 식의 유형이다.

 

또한 memoization을 활용하여 방문한 그리드는 memo에 바로 return해주는 DP의 경우를 바로 사용하는 예제 또한 중요하다.

아래 두 문제가 대표 예시이다. 
코드의 얼개를 기억하고 바로바로 구현할 수 있도록 체화하자.

https://www.acmicpc.net/problem/1520

 

1520번: 내리막 길

여행을 떠난 세준이는 지도를 하나 구하였다. 이 지도는 아래 그림과 같이 직사각형 모양이며 여러 칸으로 나뉘어져 있다. 한 칸은 한 지점을 나타내는데 각 칸에는 그 지점의 높이가 쓰여 있으

www.acmicpc.net

m, n = [int(x) for x in input().split()]
maps = [ [int(x) for x in input().split()] for _ in range(m) ]

move_x = [-1,1,0,0]
move_y = [0,0,1,-1]

def DFS(x, y, memo={}) :
    ## 변수 정의, 4 방향으로 쭉 searching해온 경로 값이 누적
    cnt = 0

    ### 종점
    if (x,y) == (m-1,n-1) :
        cnt += 1
        return cnt

    if (x,y) in memo :
        return memo[(x,y)]

    for i in range(4) :
        after_x = x+move_x[i]
        after_y = y+move_y[i]

        if after_x < 0 or after_y < 0 or after_x >= m or after_y >= n :
            continue

        if maps[after_x][after_y] < maps[x][y] :
            cnt += DFS(after_x,after_y,memo)

    ### Memoization
    memo[(x,y)] = cnt
    return cnt

print(DFS(0,0))

 

https://www.acmicpc.net/problem/1890

 

1890번: 점프

첫째 줄에 게임 판의 크기 N (4 ≤ N ≤ 100)이 주어진다. 그 다음 N개 줄에는 각 칸에 적혀져 있는 수가 N개씩 주어진다. 칸에 적혀있는 수는 0보다 크거나 같고, 9보다 작거나 같은 정수이며, 가장

www.acmicpc.net

N = int(input())

maps = [ [int(x) for x in input().split()] for _ in range(N)]

move_x = [1,0]
move_y = [0,1]

def DFS(x,y,memo={}) :
    cnt = 0

    if (x,y) == (N-1,N-1) :
        ### 가장 오른쪽 밑으로 도달한 경우는 count가 됨
        cnt += 1
        return cnt
    
    ### 하지만 그 외의 경우는 count가 되지 않고 return만 해줌
    if maps[x][y] == 0 :
        return cnt
        
    if (x,y) in memo : 
        return memo[(x,y)]

    for i in range(2) :
        after_x = x+move_x[i]*maps[x][y]
        after_y = y+move_y[i]*maps[x][y]

        if after_x < 0 or after_y < 0 or after_x >= N or after_y >= N :
            continue

        cnt += DFS(after_x,after_y,memo)
        
    memo[(x,y)] = cnt
    return cnt


print(DFS(0,0))