[Java] 백준 14501번

박세윤·2022년 5월 8일
0

BaekJoon Online Judge

목록 보기
43/95
post-thumbnail

백준 14501번

퇴사

문제

상담원으로 일하고 있는 백준이는 퇴사를 하려고 한다.

오늘부터 N+1일째 되는 날 퇴사를 하기 위해서, 남은 N일 동안 최대한 많은 상담을 하려고 한다.

백준이는 비서에게 최대한 많은 상담을 잡으라고 부탁을 했고, 비서는 하루에 하나씩 서로 다른 사람의 상담을 잡아놓았다.

각각의 상담은 상담을 완료하는데 걸리는 기간 Ti와 상담을 했을 때 받을 수 있는 금액 Pi로 이루어져 있다.

N = 7인 경우에 다음과 같은 상담 일정표를 보자.

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)

출력

첫째 줄에 백준이가 얻을 수 있는 최대 이익을 출력한다.

예제

알고리즘 분류

  • 다이나믹 프로그래밍
  • 브루트포스 알고리즘

코드

import java.util.*;
import java.io.*;

public class Main {
	public static int arr[][];
	public static int result;
	public static int N;
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		N = Integer.parseInt(br.readLine());
		result = 0;
		arr = new int[N][2];
		
		for(int i=0; i<N; i++) {
			StringTokenizer st = new StringTokenizer(br.readLine(), " ");
			arr[i][0] = Integer.parseInt(st.nextToken());
			arr[i][1] = Integer.parseInt(st.nextToken());
		}
		
		DFS(0, 0);
		
		System.out.println(result);
	}
	
	public static void DFS(int day, int pay) {
		if(day >= N) {
			result = Math.max(result, pay);
			return;
		}
		
		if(day + arr[day][0] <= N)
			DFS(day + arr[day][0], pay + arr[day][1]);
		else
			DFS(day + arr[day][0], pay);
		
		DFS(day + 1, pay);
	}
}

풀이

DFS로 문제를 해결하였다.
arr[i][0]에는 날짜를, arr[i][1]에는 벌 수 있는 돈을 입력했다.

DFS 함수 내부를 살펴보자면,
처음에 if(day>=N) 파트는 매 줄기 마다 기존의 최댓값과 비교하여 새로운 최댓값을 계산하는 파트이다.
if(day + arr[day][0] <= N) 파트에서는, 날짜가 오버되지 않을 때 점화식이고, else에서는 날짜가 오버되어 돈을 못받는 상황이라, 일은 못하고 그냥 날짜만 지나가는 상황이다.
마지막으로 DFS(day + 1, pay) 파트에서는 처음으로 1일차 때 일을 시작한 경우부터 시작해서 1일씩 늘려 2일차 시작의 경우, 3일차 시작의 경우 ... 등등 모든 경우를 탐색하기 위한 장치이다. 여기서 탐색된 모든 경우가 첫 파트에서 최댓값 계산에 사용된다.

profile
개발 공부!

0개의 댓글