https://www.acmicpc.net/problem/1697
호호호호
뭔가
느낌이
..
DP느낌이 났어요
딱 문제 보자마자
[동적프로그래밍] 백준 1463번 1로 만들기(C++)
[동적프로그래밍] 백준 1463번 1로 만들기(C++)
https://www.acmicpc.net/problem/1463 오우 1로 만들기 문제! 문제는 정말 간단하다 3으로 나누거나 2로나누거나 1로빼서 정수 n을 1로 만들때, 몇번 연산을 진행했는지에 대해 최솟값을 출력하라고 하
lee-soo.tistory.com
어라..
1로 만들기랑 비슷한데
아예 이렇게 dp로 틀어서도 문제를 풀 수 있지만
BFS를 열렬히 풀고있는 내겐 BFS만 보였다고
휘비고
문제 자체는 이해했을 것이다
예제에 5 17의 경우
5 -> 4 -> 8 -> 16 -> 17
이렇게 총 4번의 다리를 건너는 경우가 제일 빠르다
(이 4번 말고도 여러개 존재)
이걸 BFS로 어떻게 했냐면
살짝 DP를 이용했다
먼저 크게 3가지의 경우의 수가 존재한다
+1
-1
*2
이걸 어떻게 하냐고?
다 고려해보면 된다
queue에는, +1 -1 *2를 한 값을 넣어주고
그상태 그대로 dp[]값을 +1한채로 채워주면 된다.
이후 재방문하지 않게 visted를 사용하였다.
어라 그럼 어떻게 그게 최솟값인게 자명하죠? 란 생각이 들 수 있다.
사실 이 값이 최솟값이 아니게 되려면
예를들어
1 6을 보자
dp[6]의 값을 구하면 되는 건데
이게
dp[5] 와 dp[7]과 d[3]에서 +1한 값중에 가장 최소가 되어야 하는게 아닌가?
근데 내가 하려는 식은 단순히 조건문도 없이 그저 바로 넣어주는 것인데
..
이런 고민을 한 내가 멍청했다
dp를 이용해서 값을 이미 집어넣고 난 후에는 , 그값은 최솟값인게 자명하다
예를들어 dp[6]의 값을 3*2를통해서 dp[3]+1로 넣었을 때 dp[5]+1보다 작을 가능성을 생각한게 아닌가?
그런 경우는 없다.
dp[]는 순서대로 채워지기 때문에, 만약 dp[5]+1이 dp[3]+1보다 작다면 당연히 dp[5]가 dp[3]보다 순서상 빨리 오는거다
예를들어
5 17을 보자
5 -> 10 -> 9 -> 18 -> 17의 순서로 갈때
5에서는
4 6 10의 경우의수로
이후 4 6 10은
3,8,7,12,20,9
..
로 갈때 20이란 수의 dp값을 봐보자
20 dp는 dp[10]+1인데 19와 21이 있는가?
당연히 없다
뭐 아직도 살짝 헷갈리긴 하는데 자주자주 봐서 생각해보자
'코딩 테스트 준비! (백준) > BFS' 카테고리의 다른 글
[BFS] 백준 14226번 이모티콘(C++) (0) | 2025.05.09 |
---|---|
[BFS] 백준 13913번 숨바꼭질 4 (C++) (0) | 2025.05.08 |
[BFS] 백준 2146번 다리 만들기(C++) (0) | 2025.05.08 |
[BFS] 백준 16940 BFS 스폐셜 저지(C++) (0) | 2025.05.02 |
[BFS] 백준 7562번 나이트의 이동(C++) (0) | 2025.04.30 |