문제 링크: https://www.acmicpc.net/problem/31804
문제
자료구조 시험에서 우찬이는 a점을 받았고, 상훈이는 우찬이보다 높은 b점을 받았다. 우찬이는 상훈이보다 점수가 낮아서 화가 났지만, 공부를 하나도 하지 않아서 상훈이보다 시험을 잘 볼 수는 없다는 것을 알고 있었다. 하지만 우찬이는 최소한 동점을 받고 싶었기 때문에, 자신의 수를 바꾸는 마법을 배워서 다음 3가지 마법을 사용할 수 있게 되었다.
- 물 주기: 수에 물을 주면 수가 1 커진다.
- 밥 주기: 수에 밥을 주면 수가 2배가 된다.
- chance!: 수에 chance!를 외치면 수가 10배가 된다.
하지만 chance!를 외치면 목이 너무 아프기 때문에 우찬이는 chance! 마법을 최대 한 번만 사용할 수 있다. 그리고 마법을 사용할 때마다 팔을 이리저리 휘저어야해서 힘이 많이 들기 때문에 마법을 최소한으로 사용하고자 한다. 우찬이가 상훈이와 동점이 되도록 하려고 할 때 마법을 최소한으로 사용하도록 도와주자.
입력
첫 번째 줄에 우찬이와 상훈이의 점수 a와 b가 공백으로 구분되어 주어진다.
출력
첫 번째 줄에 a를 b로 만들기 위해 필요한 최소 마법 사용 횟수를 출력한다.
풀이
접근법
- BFS를 이용할 수도 있지만, 단순히 수가 커지고 있기 때문에(작아지지 않음) bottom-up 방식의 dp로 접근해도 괜찮을 것 같다.
- 각 분기를 생각하면서 조건에 따라 dp 배열을 채워준다. => 코드 각주 참고
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
// 14:25 ~
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
// BFS를 이용할 수도 있지만, 단순히 수가 커지고 있기 때문에(작아지지 않음) bottom-up 방식의 dp로 접근해도 괜찮을 것 같다.
int[][] dp = new int[b+1][2];
for(int i=0;i<=b;i++) Arrays.fill(dp[i], -1);
dp[a][0] = 0;
// 현재 수
for(int i=a+1;i<=b;i++) {
// 물주기
dp[i][0] = dp[i-1][0] + 1;
// 만약 이전에 chance를 외친 적이 있다면
if (dp[i-1][1] != -1) dp[i][1] = dp[i-1][1] + 1;
// 만약 밥을 줄 수 있다면
if(i%2 == 0 && dp[i/2][0] != -1) {
dp[i][0] = Math.min(dp[i][0], dp[i/2][0] + 1);
if (dp[i/2][1] != -1) dp[i][1] = dp[i][1] == -1 ? dp[i/2][1]+1 : Math.min(dp[i][1], dp[i/2][1] + 1);
}
// 만약 chance를 외칠 수 있다면
if (i%10 == 0 && dp[i/10][0] != -1) {
dp[i][1] = dp[i][1] == -1 ? dp[i/10][0] + 1 : Math.min(dp[i][1], dp[i/10][0] + 1);
}
}
int ans = 0;
if (dp[b][0] != -1 && dp[b][1] != -1) ans = Math.min(dp[b][0], dp[b][1]);
else ans = Math.max(dp[b][0], dp[b][1]);
System.out.println(ans);
}
}
'Java > 문제풀이' 카테고리의 다른 글
[백준 30464] 시간 낭비 - Java 문제풀이 (2) | 2024.05.23 |
---|---|
[백준 1038] 감소하는 수 - Java 문제풀이 (0) | 2024.05.20 |
[백준 9077] 지뢰제거 - Java 문제풀이 (0) | 2024.05.17 |
[백준 2660] 회장뽑기 - Java 문제풀이 (0) | 2024.05.16 |
[백준 22166] 창영이와 퇴근 - Java 문제풀이 (0) | 2024.05.14 |