Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

전공공부

[BOJ 14501] 퇴사 본문

Study/Problem Solving

[BOJ 14501] 퇴사

monitor 2023. 3. 29. 23:31

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

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

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

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

 

예제 케이스

Ti : 걸리는 시간

Pi : 최대 이익

 

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이다.

 

그러면 이때 얻을 수 있는 최대 이익을 위와 같이 구하는것이 오늘의 목표이다.

 

나는 구할때 dp와 brute force를 활용한 풀이를 다른 블로그에서 참고하여 문제를 풀었다.

 

해당 풀이에 따르면 거꾸로 가서 탐색하는것이 최대한의 이익을 구할 수 있는 쉬운 풀이법이라 설명하고 있다.

 

왜냐하면 뒤에서 부터 가져가면서 체킹 할 경우 처음 들어오는 값이 최대한의 이익을 가져오는 값이고 들어오는 값들은 이미 전에 들어온 값과 비교하면서 진행 할 수 있기 때문이다.

 

이때 비교하는 부분이 핵심 포인트가 되는데, 뒤에서 부터 진행 하니 dp[i]의 값을 dp[i+1] 로 부터 가져온다.

 

T[i](걸리는 시간) + i(현재의 시간) 이 N+1을 넘으면 이것은 상담 할 수 없는 케이스이니 제외하고

 

T[i](걸리는 시간) + i(현재의 시간) 이 dp[i+1](현재 보다 미래에서 먼저 넣은 값)에 값과 dp[T[i]+i] + P[i] (걸리는 시간과 현재의 시간값 + 현재의 최대 이익 값 <훨씬 더 이전에 들어 온 값을 비교하여 값을 비교>)을 비교하여 더 큰 값을 dp[i]의 값으로 초기화 시켜주는 것을 반복한다.  

 

package Greedy;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class BOJ_14501{
    public static void main(String[] args) throws NumberFormatException, IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(in.readLine());
        StringTokenizer tk;
        int T[] = new int[100];
        int P[] = new int[100];
        int dp[] = new int[100];
        for(int i = 1; i <= N; i++){
            tk = new StringTokenizer(in.readLine());    
            T[i] = Integer.valueOf(tk.nextToken());
            P[i] = Integer.valueOf(tk.nextToken());
        }
        int next = 0;
        for(int i = N; i > 0; i--){
            next = T[i] + i;
            if(next > N+1){
                dp[i] = dp[i+1];
            }else{
                dp[i] = Math.max(dp[i+1], P[i] + dp[next]);
            }
        }
        System.out.println(dp[1]);
    }
}

 

 

문제 링크 : https://www.acmicpc.net/problem/14501

'Study > Problem Solving' 카테고리의 다른 글

[PROGRAMMERS] 숫자 변환하기  (0) 2023.05.01
[PROGRAMMERS] 요격 시스템  (0) 2023.04.30
[PROGRAMMERS]연속된 부분 수열의 합  (0) 2023.04.14
[BOJ 13458] 시험 감독  (0) 2023.03.30
[Programmers] 뒤에 있는 큰 수 찾기  (0) 2023.02.07