sw/알고리즘

백준 17070 파이프 옮기기1

넉넉- 2023. 1. 24. 11:49

궁금한 점

  • 파이썬에서 재귀를 하는데 시간이 오래 안걸리는 방법이 있는지? 꼭 찾아보자. c++는 depth 백만까지도 dfs로 풀이 가능하다는데 파이썬도 그런지 확인 필요.

코드1

  • dfs 풀이
  • 효율성 테스트에서 시간 초과
  • 코드 내용
    • dfs함수는 row, col, state 3개 인자를 받는다.
    • state에 따라서 갈 수 있는 주변 노드를 확인하여 해당 노드를 다시 dfs 함수에 넣는다.
    • 함수가 재귀적으로 생성되며, (N,N)에 도달할 경우 ans + 1  
import sys

n= int(sys.stdin.readline())
graph= [list(map(int,sys.stdin.readline().split())) for _ in range(n)]
n-=1
ans = 0
def dfs(r,c,state):
    global ans
    if r==n and c == n: 
        ans += 1
        return 
    
    if state==0:
        if c < n and graph[r][c+1]==0:
            dfs(r,c+1,0) 
            if r < n and graph[r+1][c]==0 and graph[r+1][c+1]==0: dfs(r+1,c+1,2)
    elif state==1:
        if r < n and graph[r+1][c]==0:
            dfs(r+1,c,1)
            if c < n and graph[r][c+1]==0 and graph[r+1][c+1]==0: dfs(r+1,c+1,2)
    elif state==2:
        if c < n and graph[r][c+1]==0: dfs(r,c+1,0)
        if r < n and graph[r+1][c]==0: dfs(r+1,c,1)
        if c < n and r < n and graph[r+1][c+1]==0 and graph[r+1][c] ==0 and graph[r][c+1] ==0: dfs(r+1,c+1,2)

dfs(0,1,0) 
print(ans)

코드2

  • dp로 풀이
  • 코드 내용
    • dp는 3중 배열
    • dp[r][c]는 (r,c) 위치에 가로, 세로, 대각선으로 올 수 있는 경우의 수
    • dp의 1행에 대해서는 따로 초기화 / dp 1열에 대해서는 따로 초기화
    • dp의 점화식은 가로/세로/대각선 인 경우에 따라 다르게 작성
      • 가로: dp[r][c][0] = dp[r][c-1][0] + dp[r][c-1][2]
      • 세로: dp[r][c][1] = dp[r-1][c][1] + dp[r-1][c][2]
      • 대각선: dp[r][c][2] = dp[r-1][c-1][0] + dp[r-1][c-1][1] +dp[r-1][c-1][2]
import sys
sys.stdin = open("input.txt", "r") 

n= int(sys.stdin.readline())
graph= [list(map(int,sys.stdin.readline().split())) for _ in range(n)]
dp=[[[0 for _ in range(3)] for _ in range(n)]for _ in range(n)]
dp[0][1] = [1,0,0]

for i in range(2,n):
    if graph[1][i]==0:
        dp[0][i][0] = dp[0][i-1][0]

for r in range(1,n):
    for c in range(1,n):
        if graph[r][c]==0:
            dp[r][c][0] = dp[r][c-1][0] + dp[r][c-1][2]
            dp[r][c][1] = dp[r-1][c][1] + dp[r-1][c][2]
            if graph[r][c-1] == 0 and graph[r-1][c]==0:
                dp[r][c][2] = dp[r-1][c-1][0] + dp[r-1][c-1][1] +dp[r-1][c-1][2]

print(sum(dp[n-1][n-1]))