BOJ C++ 알고리즘 공부
[DP] 숨바꼭질 (1697)(C++)
kk_eezz
2024. 2. 4. 18:51
https://www.acmicpc.net/problem/1697
1697번: 숨바꼭질
수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일
www.acmicpc.net
1. 문제 개요
수빈이가 점 N(0<=N<=100,000)에 있고, 동생은 점 K(0<=K<=100,000)에 있을 때, 수빈이가 동생이 있는 위치로 가는 최소 시간을 구하는 문제. 이때, X 위치에서 X+1, X-1, 2*X 위치로 가는 데에는 각각 1초가 걸린다.
2. 입출력
3. 문제 풀이
우선, 수빈이가 동생보다 뒤에 있는 경우(N>K)와 수빈이가 동생보다 앞에 있는 경우(N<=K)로 나누어 볼 수 있다.
전자의 경우에는 -1로 이동하는 경우의 수 밖에 없으므로 정답은 N-K가 된다. 후자의 경우에는 다이나믹 프로그래밍으로 최소값을 구할 수 있다. 가능한 경우의 수는 +1, -1, *2 세 가지이므로 세가지 중에서 가장 작은 값을 선택하여 저장하면 된다.
이때, N에서 K로 가는 경우의 수를 구할때, N이하의 위치의 값이 쓰이는 경우도 있으므로 이도 구해준다.
for(int i=0;i<N;i++) { // N 이하의 값에 대해서 최솟값을 구해준다.
DP[i] = N-i;
}
for(int i=N+1;i<=K+1;i++) {
DP[i] = MAX;
if(i%2==0)
DP[i] = DP[i/2]+1;
DP[i] = min(DP[i],DP[i-1]+1);
DP[i-1] = min(DP[i-1],DP[i]+1);
}
4. 전체 코드
#include <algorithm>
#include <iostream>
using namespace std;
const int MAX = 100001;
int DP[MAX];
int main(void) {
int N, K;
scanf("%d%d",&N,&K);
if(N>K) {
printf("%d",N-K);
} else {
for(int i=0;i<N;i++) {
DP[i] = N-i;
}
for(int i=N+1;i<=K+1;i++) {
DP[i] = MAX;
if(i%2==0)
DP[i] = DP[i/2]+1;
DP[i] = min(DP[i],DP[i-1]+1);
DP[i-1] = min(DP[i-1],DP[i]+1);
}
printf("%d",DP[K]);
}
}
아직 배워가는 중이라 틀린 부분이 있을 수 있습니다. 지적할 부분이 있다면 댓글로 알려주시면 감사하겠습니다!!!