반응형
1. dp(index, left, right) : 현재 두 발의 위치가 left, right일 때 arr[index...]를 모두 밟는 최소 비용
2. dp(index, left, right) = min(왼쪽 발을 움직일 때 비용, 오른쪽 발을 움직일 때 비용)
1. dp(index, left, right) : 현재 두 발의 위치가 left, right일 때 arr[index...]를 모두 밟는 최소 비용
현재의 움직임이 나중에 어떤 영향을 미칠지 예상할 수 없으므로 다이나믹 프로그래밍으로 해결할 수 있다. 현재 두 발의 위치가 left, right일 때 arr[index...]를 모두 밟는 최소 비용을 dp(index, left, right)라고 정의하자. 위치가 5가지이므로 총 5*5*100,000개의 dp 값을 구하게 되고 시간 안에 통과가 가능하다.
2. dp(index, left, right) = min(왼쪽 발을 움직일 때 비용, 오른쪽 발을 움직일 때 비용)
현재 상황에서 할 수 있는 움직임은 두 가지이다. 왼쪽 발을 움직이거나, 오른쪽 발을 움직이는 것. cost(before, after)를 before에 위치한 발을 after로 옮기는 비용이라고 하자. 다음에 밟아야 할 위치가 next라고 하면, 왼쪽 발을 움직일 때의 비용은 cost(left, next) + dp(index+1, next, right)가 되고, 오른쪽 발을 움직일 때의 비용은 cost(right, next) + dp(index+1, left, next)가 된다. 이 중 더 비용이 적게 드는 경우를 선택하면 된다. 기저 사례는 주어진 모든 원소를 다 밟았을 때이므로 index = N일 때이다.
import Foundation
let INF = 987654321
var N = 0
var arr = [Int]()
var cache = Array(repeating: Array(repeating: Array(repeating: INF, count: 5), count: 5), count: 100_001)
func calcCost(before: Int, after: Int) -> Int {
if before == 0 {
return 2
} else if before == after {
return 1
} else if before + 2 == after || before - 2 == after {
return 4
} else {
return 3
}
}
// dp(index, left, right): 현재 두 발의 위치가 left, right일 때 arr[index...]를 모두 밟는 비용
func dp(index: Int, left: Int, right: Int) -> Int {
if index == N { return 0 }
var ret = cache[index][left][right]
if ret != INF { return ret }
let next = arr[index]
if right != next { // 왼쪽 발을 움직임
ret = min(ret, calcCost(before: left, after: next) + dp(index: index+1, left: next, right: right))
}
if left != next { // 오른쪽 발을 움직임
ret = min(ret, calcCost(before: right, after: next) + dp(index: index+1, left: left, right: next))
}
cache[index][left][right] = ret
return ret
}
func solution() {
arr = readLine()!.split(separator: " ").map{ Int(String($0))! }.dropLast()
N = arr.count
let result: Int
if N == 0 {
result = 0
} else {
result = 2 + min(dp(index: 1, left: arr[0], right: 0), dp(index: 1, left: 0, right: arr[0]))
}
print(result)
}
solution()
반응형
'Problem Solving > BOJ' 카테고리의 다른 글
백준 1766번 문제집 - C++(cpp) 풀이 (0) | 2022.02.04 |
---|---|
백준 1007번 백터 매칭 - 스위프트(Swift) 풀이 (0) | 2022.02.04 |
백준 2143번 두 배열의 합 - 스위프트(Swift) 풀이 (0) | 2022.02.03 |
백준 1644번 소수의 연속합 - 스위프트(Swift) 풀이 (0) | 2022.02.03 |
백준 12100번 2048 (Easy) - 스위프트(Swift) 풀이 + 그림 설명 (0) | 2022.01.29 |
댓글