Skip to content

Commit 8ca2278

Browse files
authored
Merge pull request #148 from learntosurf/main
Learntosurf / 2월 3주차 / 2문제
2 parents 5b61f3f + 694186e commit 8ca2278

File tree

3 files changed

+106
-0
lines changed

3 files changed

+106
-0
lines changed

_WeeklyChallenges/W12-[DP]/Assignment_BOJ_1520_내리막길.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,39 @@
44
유형: Dynamic Programming, Graph Theory, Graph Traversal, Depth-First Search
55
'''
66

7+
import sys
8+
sys.setrecursionlimit(10**6)
9+
input = sys.stdin.readline
10+
11+
# 방향 벡터 (상, 하, 좌, 우)
12+
dx = [-1, 1, 0, 0]
13+
dy = [0, 0, -1, 1]
14+
15+
def dfs(x, y):
16+
# 도착점에 도달하면 경로 1개 반환
17+
if x == M - 1 and y == N - 1:
18+
return 1
19+
20+
# 이미 방문한 적이 있다면 저장된 경로 개수 반환
21+
if dp[x][y] != -1:
22+
return dp[x][y]
23+
24+
# 현재 위치에서 가능한 경로 개수 계산
25+
dp[x][y] = 0 # 초기화
26+
for i in range(4):
27+
nx, ny = x + dx[i], y + dy[i]
28+
if 0 <= nx < M and 0 <= ny < N and graph[nx][ny] < graph[x][y]: # 내리막길 조건
29+
dp[x][y] += dfs(nx, ny)
30+
31+
return dp[x][y]
32+
33+
# 입력 처리
34+
M, N = map(int, input().split())
35+
graph = [list(map(int, input().split())) for _ in range(M)]
36+
37+
# DP 배열 (-1로 초기화)
38+
dp = [[-1] * N for _ in range(M)]
39+
40+
# 결과 출력
41+
H = dfs(0, 0)
42+
print(H)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import sys
2+
input = sys.stdin.readline
3+
4+
# 입력
5+
N, M = map(int, input().split()) # 지도의 크기
6+
grid = [list(map(int, input().split())) for _ in range(N)] # 각 지역의 가치
7+
8+
# DP 테이블
9+
dp = [[0] * M for _ in range(N)]
10+
11+
# 첫 번째 행 초기화 (왼쪽에서 오른쪽으로 누적합)
12+
dp[0][0] = grid[0][0]
13+
for j in range(1, M):
14+
dp[0][j] = dp[0][j-1] + grid[0][j] # (0,1)→(0,2)→(0,3)..
15+
16+
# 두 번째 행부터 (왼쪽에서 오른쪽, 오른쪽에서 왼쪽으로 진행)
17+
for i in range(1, N):
18+
left_to_right = [0] * M
19+
right_to_left = [0] * M
20+
21+
# 왼쪽 → 오른쪽
22+
left_to_right[0] = dp[i-1][0] + grid[i][0] # 첫번째 열은 위쪽에서만 올 수 있음
23+
for j in range(1, M): # 두번째 열부터는 위쪽, 왼쪽에서 오는 경우 중 선택
24+
left_to_right[j] = max(dp[i-1][j], left_to_right[j-1]) + grid[i][j]
25+
26+
# 오른쪽 → 왼쪽
27+
right_to_left[M-1] = dp[i-1][M-1] + grid[i][M-1] # 마지막 열은 위쪽에서만 올 수 있음
28+
for j in range(M-2, -1, -1): # 그 다음 열부터는 위쪽, 오른쪽에서 오는 경우 중 선택
29+
right_to_left[j] = max(dp[i-1][j], right_to_left[j+1]) + grid[i][j]
30+
31+
# 두 개의 배열을 비교해 dp[i][j] 갱신
32+
for j in range(M):
33+
dp[i][j] = max(left_to_right[j], right_to_left[j])
34+
35+
print(dp[N-1][M-1]) # 마지막 위치에 저장된 값이 탐사한 지역 가치 합의 최대값
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import sys
2+
sys.setrecursionlimit(10**6)
3+
input = sys.stdin.readline
4+
5+
# 방향 벡터 (상, 하, 좌, 우)
6+
dx = [-1, 1, 0, 0]
7+
dy = [0, 0, -1, 1]
8+
9+
def dfs(x, y):
10+
# 도착점에 도달하면 경로 1개 반환
11+
if x == M - 1 and y == N - 1:
12+
return 1
13+
14+
# 이미 방문한 적이 있다면 저장된 경로 개수 반환
15+
if dp[x][y] != -1:
16+
return dp[x][y]
17+
18+
# 현재 위치에서 가능한 경로 개수 계산
19+
dp[x][y] = 0 # 초기화
20+
for i in range(4):
21+
nx, ny = x + dx[i], y + dy[i]
22+
if 0 <= nx < M and 0 <= ny < N and graph[nx][ny] < graph[x][y]: # 내리막길 조건
23+
dp[x][y] += dfs(nx, ny)
24+
25+
return dp[x][y]
26+
27+
# 입력 처리
28+
M, N = map(int, input().split())
29+
graph = [list(map(int, input().split())) for _ in range(M)]
30+
31+
# DP 배열 (-1로 초기화)
32+
dp = [[-1] * N for _ in range(M)]
33+
34+
H = dfs(0, 0)
35+
print(H)

0 commit comments

Comments
 (0)