(전공복습) 데이터과학 4. 시각화
차례
꽤 어려운 DP 문제.
dp[i][j][k]
를 i
번째 순서에서 왼쪽 발이 j
, 오른쪽 발이 k
위치에 있을 때의 드는 힘의 최솟값으로 정의하자(그것이 불가능한 경우 INF
로 정의한다).
개인적으로 이 문제에선 dp[i][j][k]
를 계산하는 것보다 dp[i+1][j][k]
를 계산하는 것이 직관적이라 그렇게 했다.
또한, 처음에는 오직 오른발만 움직이는 것으로 고정을 해두었는데, 실제로는 좌우가 바뀐 경우가 나와 중복되는 계산을 하게 되기 때문이다.
아래 코드를 보면, 두 발이 같은 위치에 가는 경우에 대한 예외처리가 없는데, 그럼에도 AC를 받은 것은 다음과 같은 이유 때문인 듯하다:
(2, 4)
에 있다면, (4, 4)
로 이동하고 3
을 누르는 것(4+3)보다, (2, 4)
에 그대로 두고 3
을 누르는 것(1+3)이 이득이다.(3, 4)
에 있다면, (4, 4)
로 이동하고 1
을 누르는 것(3+3)보다, (3, 4)
에 그대로 두고 1
을 누르는 것(1+4)이 이득이다.1
을 누르는 것보다, 원래 위치에 두고 같은 발로 다시 누르는 것이 이득이다.INF = float('inf')
# src에서 dst로 발을 옮길 때 드는 비용을 반환함
def step(src, dst):
if not src:
return 2
elif src == dst:
return 1
elif abs(src-dst) in (1, 3):
return 3
else:
return 4
arr = list(map(int, input().split()))[:-1]
n = len(arr)
dp = [[[INF] * 5 for _ in range(5)] for _ in range(n)]
# 처음에는 무조건 한쪽 발(오른발)만 움직인다
dp[0][0][arr[0]] = 2
for i in range(n-1):
for j in range(5):
for k in range(5):
if dp[i][j][k] != INF:
# dp 수행 부분
dp[i+1][arr[i+1]][k] = min(dp[i+1][arr[i+1]][k], dp[i][j][k] + step(j, arr[i+1]))
dp[i+1][j][arr[i+1]] = min(dp[i+1][j][arr[i+1]], dp[i][j][k] + step(k, arr[i+1]))
# dp[-1]을 flatten하고 거기서 최솟값 출력
print(min((e for line in dp[-1] for e in line)))
문제 링크 문제 링크
개요 선형적인 자료구조에서는 값에 접근하는 데에 \(O(1)\)이면 충분하지만, 대신 부분합을 구하는 데에는 \(O(N)\)이 필요하다. 그렇다면 이 자료구조를 이진 트리로 구성하면 어떨까? 값에 접근하는 데에 걸리는 시간이 \(O(\lg N)\)으로 늘어나지만 대신 부분합을 구하...
개요 다익스트라 알고리즘과 함께 Single Sourse Shortest Path(SSSP) 문제를 푸는 알고리즘이다. 즉, 한 노드에서 다른 모든 노드로 가는 최단 경로를 구하는 알고리즘이다. 다익스트라 알고리즘보다 느리지만, 음수 가중치 간선이 있어도 작동하며, 음수 가중치 사...
개요 다익스트라 알고리즘은 Single Sourse Shortest Path(SSSP) 문제를 푸는 알고리즘 중 하나이다. 즉, 한 노드에서 다른 모든 노드로 가는 최단 경로를 구하는 알고리즘이다. 단, 다익스트라 알고리즘은 음수 가중치 엣지를 허용하지 않는다. 이 경우에는 벨만-...