-
Notifications
You must be signed in to change notification settings - Fork 0
5-YooGyeongMo #30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
5-YooGyeongMo #30
Conversation
백준 - DP문제
YooGyeongMo/DP/RGB거리.swift
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
입력값을 보고 재귀가 깊어졌을 때 Depth가 얼마정도 될지 최악의 상황을 고려하면 탑다운을 할지 바텀업을 할지 알수있어요.
라고 하셨는데, 어느정도 깊을 때 탑다운을 직감할 수 있을까요 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
제 생각이지만..
집의 최대 수가 1000이고, r/g/b로 분기가 총 3개여서
이런 경우엔 가볍게 생각해보면 최악의 경우 3^1000이기 때문에,
호출이 너무 많으니? 탑다운은 안돼! 이런 느낌으로 이해했습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- 전 처음에 BFS일줄 알았습니다.. 시간제한보고 Dp일거라 생각은 했는데, 이게 집이 3개라서 Dp배열이 그럼 3개가 필요한가?하면서 2차원배열 생각안하고 넘겨서 시간을 많이 소모한 것 같습니닷.
결국 힌트 참고하면서 데미안코드랑 거의 똑같하게 풀려서 그냥 제 버리게된 코드를 첨부합니다.
아래는 물론 메모리초과뜨는 코드입니다. (시간초과가 안뜨고 , 45%까지는 올라가더라구요)
cursor안쓰고removeFirst()써서풀었을때는 바로 시간초과뜨는거보면 확실히 cursor쓰는 BFS가 기존 BFS보다는 swift에서 빠르게 푸는 방식임을 체감했습니다.
수도
- 첫번째 집 색칠 초기값 설정
- 큐에다가 현재 색칠, 색상, 현재까지의 비용을 담아줬어요
- 그렇게 BFS돌면서 최종에서 min 값을 비교하고 있습니다. (index==N-1)
나름 배운점
당연한거간한데, 숫자값에 대해서는 그냥 반복문 돌릴때도 idx,item,index 이런식으로 해줬는데, 이번에 좀 정신없어서 이렇게 nextColor로 반복문 돌리니까 훨씬 편하네요.
for nextColor in 0 ..< 3 func solution(_ N: Int, _ costs: [[Int]]) -> Int {
var minCost = Int.max
var queue: [(idx: Int, color: Int, cost: Int)] = []
var cursor = 0
// 1번 집 먼저 색칠하기
queue.append((0, 0, costs[0][0]))
queue.append((0, 1, costs[0][1]))
queue.append((0, 2, costs[0][2]))
while cursor < queue.count {
let (index, color, cost) = queue[cursor]
if index == N - 1 {
minCost = min(minCost, cost)
} else {
for nextColor in 0 ..< 3 {
if color == nextColor { continue }
queue.append((index + 1, nextColor, cost + costs[index + 1][nextColor]))
}
}
cursor += 1
}
return minCost
}
giljihun
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저도 데미안 전략과 동일한거같네요
이전 집에서 고를 수 있는 두 색 중 최소 비용을 선택해 누적.
새롭게 알게 된 내용 << 바텀업 vs 탑다운 내용이 흥미로워서
저도 나름대로 정리해보려고 했습니다! 감사해요.
DP의 방식. 탑다운(재귀) vs 바텀업(반복문) ?
예를들어, 피보나치를 생각해보면 탑다운으로 문제를 쪼개고 쪼개서
지구의 내핵까지 들어가게됩니다. (깊은 호출 스택!! 뎁스!)
물론, DP는 메모리를 저장하니 최적화가 들어가긴 하지만요.
그래도 뎁스가 커지면 입력 크기가 크거나 분기가 많으면 overflow 가능성이 높아지죠.
최대 1000개의 데이터 + 3가지 분기(R, G, B) -> 3^1000.
그래서 이런 경우에, 바텁업 방식이 적합한 것 같습니다!
맨 처음 집은 입력값대로 초기화 -> 2번집부터 순차적으로 계산!
그렇게 누적 cost 중 가장 작은 값을 선택~
이건 그냥 입력부
guard let N = Int(readLine() ?? ""),
N > 2, N < 1000 else { exit(0) }
var houseCost: [[Int]] = []
(0..<N).forEach { _ in
guard let input = readLine()?.split(separator: " "),
input.count == 3,
let R = Int(String(input[0])),
let G = Int(String(input[1])),
let B = Int(String(input[2])) else { exit(0) }
houseCost.append([R, G, B])
}
YooGyeongMo/DP/RGB거리.swift
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
제 생각이지만..
집의 최대 수가 1000이고, r/g/b로 분기가 총 3개여서
이런 경우엔 가볍게 생각해보면 최악의 경우 3^1000이기 때문에,
호출이 너무 많으니? 탑다운은 안돼! 이런 느낌으로 이해했습니다.
🔗 문제 링크
RGB거리
RGB를... AI수업말고 보게되다니 ... !!!
✔️ 소요된 시간
딱 29분 59초 ㄹㅇ 임 ㅋ

✨ 수도 코드
먼저 손으로 문제의 조건들을 쭉 적어보았습니다.
중구 난방이긴 한데예 ㅋ⫬ㅋ⫬ㅋ⫬ㅋ⫬ㅋ⫬ㅋ⫬ㅋ⫬ㅋ⫬ㅋ⫬ㅋ⫬ 작성을 하다보면, 해당 규칙을 알 수 있었는데요.
1,2,3에서 말하는 점에서 딱 보았을때, 저는 브루트포스로 할까? 라는 생각을 했었던거 같아요.
이제는 그래도 짬이 조금 생겨서 그때 그러면 문제를 분해하고 좀 더 쪼개고 해결할 수 있지 않을까? 라고 접근하니 대부분 되는거 같긴했어요.
물론 아직,, 문제를 보자마자 이해하는 점은 멀었습니다... 사실은 이 문제에서는 좀 또렷하게 보인게, 브루트포스로하면 depth가 집의 숫자에 따라 너무 깊어지는 문제가 생겨서 DP를 생각해서 최적화 점화식을 세우자라는게 나오긴했습니다. 그게 잘 안되서 문제지...만...
메인 아이디어 정리
RGB, 그리고 다음 집에서는 겹치면 안된다.가 메인 아이디어로 제 뇌리에 박혔습니다.
그러면 반대로 해당 값을 비교하기 위해서는 이전 집에서 겹치지 않은 2가지 색 중에서 최소 값을 가져와서 누적합을 하면되지않을까 ? -> 최소비용누적합
그로 저는 하나의 동일한 배열이 하나 더 생성하고, 그 배열에서 i 값을 원본 배열의 i-1값을 비교하면 어떨까 ? 라는 접근을 통해서 규칙보다는 좀 더 효율적인 방법을 발견했어요.
즉 ! 현재 집의 색을 결정할 때, 이전 집에서 고를 수 있는 두 색 중 최소 비용을 선택해 누적한다 !
그리고 마지막 요소 값중 최소값만 추출하면 되겠다 !!
수기정리본
제 코드에서는 아래와 같은 점화식이 세워졌어요.
📚 새롭게 알게된 내용
입력값을 보고 재귀가 깊어졌을 때 Depth가 얼마정도 될지 최악의 상황을 고려하면 탑다운을 할지 바텀업을 할지 알수있어요.
탑다운의 예인, 피보나치로 예를 들어보자면 점화식으로 깊어지는 부분이 어느정도 감이오지만, 실제 문제에서는 입력의 최대 범위와 분기 수를 같이 보고 재귀 깊이 * 분기 수가 감당 가능한지 판단해야 하는것 같아 DP문제가 어려운거 같아요.
해당 문제에서는 1000까지 그리고 브루트포스로도 뭔가 깊이감이 꽤나 깊어짐을 알수 있었던 문제가 아닌가합니다. 입력값이 좀 노골적으로 들어나있다 ? 그래서 저는 재귀보다는 반복문으로 해결가능한 문제를 위해 점화식을 세웠고, 반복문을 활용하는 바텀업 방식을 통해서 문제를 해결했습니다.