-
[Baekjoon Online Judge] 14501번: 퇴사문제 풀이/Baekjoon Online Judge 2021. 2. 13. 12:35
14501번: 퇴사
첫째 줄에 백준이가 얻을 수 있는 최대 이익을 출력한다.
www.acmicpc.net
요구사항
- 오늘부터 N+1일째 되는 날 퇴사를 하기 위해서, 남은 N일 동안 최대한 많은 상담을 하려고 한다.
- 백준이는 비서에게 최대한 많은 상담을 잡으라고 부탁을 했고, 비서는 하루에 하나씩 서로 다른 사람의 상담을 잡아놓았다.
- 각각의 상담은 상담을 완료하는데 걸리는 기간 Ti와 상담을 했을 때 받을 수 있는 금액 Pi로 이루어져 있다.
N = 7인 경우에 다음과 같은 상담 일정표가 입력으로 주어졌다고 가정한다.
1일 2일 3일 4일 5일 6일 7일 Ti 3 5 1 1 2 4 2 Pi 10 20 10 20 15 40 200 - 1일에 잡혀있는 상담은 총 3일이 걸리며, 상담했을 때 받을 수 있는 금액은 10이다. 5일에 잡혀있는 상담은 총 2일이 걸리며, 받을 수 있는 금액은 15이다.
- 상담을 하는데 필요한 기간은 1일보다 클 수 있기 때문에, 모든 상담을 할 수는 없다. 예를 들어서 1일에 상담을 하게 되면, 2일, 3일에 있는 상담은 할 수 없게 된다. 2일에 있는 상담을 하게 되면, 3, 4, 5, 6일에 잡혀있는 상담은 할 수 없다.
또한, N+1일째에는 회사에 없기 때문에, 6, 7일에 있는 상담을 할 수 없다.
- 퇴사 전에 할 수 있는 상담의 최대 이익은 1일, 4일, 5일에 있는 상담을 하는 것이며, 이때의 이익은 10+20+15=45이다.
상담을 적절히 했을 때, 백준이가 얻을 수 있는 최대 수익을 구한다.
입력
- 첫째 줄에 N (1 ≤ N ≤ 15)이 주어진다.
- 둘째 줄부터 N개의 줄에 Ti와 Pi가 공백으로 구분되어서 주어지며, 1일부터 N일까지 순서대로 주어진다. (1 ≤ Ti ≤ 5, 1 ≤ Pi ≤ 1,000)
출력
첫째 줄에 백준이가 얻을 수 있는 최대 이익을 출력한다.
위 예시를 살펴보면, 6일 7일의 경우 T6, T7의 일수가 근무 할 수 있는 일수를 넘어서기 때문에 상담 일정을 잡을 수 없다. 최소한 5일에 잡혀있는 상담부터 진행 할 수 있다.
4일의 상담 소요 시간은 1일이다. 당일에 끝낼 수 있다. 4일과 5일을 진행하면 총 얻을 수 있는 수익은 20 + 15로 35이다.
3일의 상담 소요 시간은 1일이다. 당일에 끝낼 수 있다. 3일, 4일, 5일을 진행하며 총 얻을 수 있는 수익은 20 + 15 + 10으로 45이다.
2일의 상담 소요 시간은 5일이다. 즉 7일 부터 다시 상담이 가능하다. 7일은 소요 시간이 2일이기 때문에 상담을 진행 할 수 없다. 결국 얻을 수 있는 수익은 0 + 20으로 20이 된다. 이렇게 되면 차라리 상담을 진행하지 않고 3, 4, 5일을 진행하는 수익이 더 높게 된다.
1일의 상담 소요 시간은 3일이다. 즉 4일 부터 다시 상담이 가능하다. 4일 부터 얻을 수 있는 수익은 위에서 구했던 대로 35이다. 1일의 수익은 10이다. 35 + 10은 45의 수익을 얻을 수 있다.
결국 1일 4일 5일 상담일은 하면 45의 수익을 얻을 수 있고, 3일 4일 5일 상담을 해도 45의 수익을 얻을 수 있다. 이것을 dp 테이블에 정리하였다.
1 2 3 4 5 6 7 dp 45 45 45 35 15 0 0 중점적으로 살펴볼 부분은 상담을 안할 수도 있다는 것이다. 상담을 안하면 이전까지 받을 수 있는 가장 최고의 수익을 유지할 수 있다.
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Baekjoon14501 { public static void main(String[] args) throws IOException { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(bufferedReader.readLine()); int[] t = new int[n + 1]; int[] p = new int[n + 1]; int[] dp = new int[n + 2]; for (int i = 1; i <= n; i++) { String[] input = bufferedReader.readLine().split(" "); t[i] = Integer.parseInt(input[0]); p[i] = Integer.parseInt(input[1]); } for (int i = n; i > 0; i--) { // 상담을 할 수 있는지 판별하기 위해 상담을 시작 할 수 있는 day를 구한다. int day = i + t[i]; // 입력받은 day가 상담할 수 있는 날보다 크게되면 상담을 할 수 없으므로 이전 수익을 유지한다. if (day > n + 1) dp[i] = dp[i + 1]; // 상담이 가능하면, 이전 수익과 오늘 얻을 수 있는 수익 + day까지 얻을 수 있는 수익을 비교한다. else dp[i] = Math.max(dp[i + 1], p[i] + dp[day]); } System.out.println(dp[1]); bufferedReader.close(); } }
DFS를 활용한 풀이
다이나믹 프로그래밍이 아닌 DFS를 활용한 방식으로 풀이를 찾아보았다.
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; class Baekjoon14501 { private static int n, answer = 0; private static int[] t, p; public static void main(String[] args) throws IOException { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); n = Integer.parseInt(bufferedReader.readLine()); t = new int[n + 1]; p = new int[n + 1]; for (int i = 1; i <= n; i++) { String[] input = bufferedReader.readLine().split(" "); t[i] = Integer.parseInt(input[0]); p[i] = Integer.parseInt(input[1]); } dfs(1, 0); System.out.println(answer); } private static void dfs(int day, int value) { // day 가 n + 1 이상이 되면 퇴사를 진행한다. if (day >= n + 1) { answer = Math.max(answer, value); return; } // today 에 상담을 하는 경우 다음 상담 day 는 n + 1 day 를 넘을 수 없다. if (day + t[day] <= n + 1) dfs(day + t[day], value + p[day]); // today 에 상담을 하지 않는 경우 다음날로 넘어간다. if (day + 1 <= n + 1) dfs(day + 1, value); } }
상담을 할 때와 안할 때를 기준으로 깊은 탐색을 진행한다. day가 n + 1이 되면 퇴사를 진행하기 때문에 적절하게 return하여 처리해준다.
DFS 관련해서는 아직 확실하게 와닿는 느낌이 없어서 지속적으로 DFS에 대한 공부를 해야 할 것 같다.
'문제 풀이 > Baekjoon Online Judge' 카테고리의 다른 글
[Baekjoon Online Judge] 1620번: 나는야 포켓몬 마스터 이다솜 (0) 2021.02.15 [Baekjoon Online Judge] 1620번: LCS 2 (0) 2021.02.15 [Baekjoon Online Judge] 9461번: 파도반 수열 (0) 2021.02.13 [Baekjoon Online Judge] 10942번: 팰린드롬? (0) 2021.02.12 [Baekjoon Online Judge] 1120번: 문자열 (0) 2021.02.12