Algorithm/acmicpc.net

악 DP!!

winney916 2022. 1. 19. 15:48
728x90

#14501번 퇴사 https://www.acmicpc.net/problem/14501

 

14501번: 퇴사

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

www.acmicpc.net

여러 방법을 시도했지만 자꾸 부분정답이 나왔다. 

 

부분 정답이 나올 때에는 과감하게 갈아엎는 것도 나쁘지 않다고 생각한다.

 

나는 잡고 늘어지다가 결국엔 구글링...

 

솔루션은 신기했다

dp를 거꾸로, 맨 뒤 index부터 접근하는 방식이었다.

아무래도 그렇게 하는게 날짜를 계산하기 쉽겠지...

 

dp의 길이는 날짜보다 1 더 길다.

초기값인 0을 설정해주기 위해서다.

 

앞서 말했듯 뒤에서부터 진행한다.

현재 날짜 (일을 받은 날짜)에 일을 진행하는 기간(d)을 더했을 때, N을 초과하면 안된다.

초과할 경우에는 (작업을 진행할 수 없다.) 오른쪽에 있는 값을 넣어준다. (시작은 0)

작업을 진행할 수 있는 경우에는 최댓값을 구해주는데

 

작업을 진행하지 않고 오른쪽에 있는 값을 그대로 받았을 경우 : dp[i+1]

작업을 진행할 경우 :  작업의 이익 + 현재날짜로부터 작업기간이 지난 날이 갖고있는 dp값

 

중 큰 값을 저장해주면 된다.

 

결과적으로는 0번 인덱스에 최댓값이 저장된다.

import sys
N = int(input())
profits = [0]*N
times = [0]*N
for i in range(N):
    t, p = map(int, sys.stdin.readline().split())
    if t <= N-i:
        profits[i] = p
        times[i] = t

dp = profits + [0]

for i in range(N-1, -1, -1): # 뒤에서 부터 진행
    if times[i] + i > N:    # 현재 날짜 + 진행일수 > N일 경우에는 -> 작업 진행 불가
        dp[i] = dp[i+1]     # 오른쪽에 있는 값 저장 (초기 0)
    else:                   # 작거나 같을 때 -> 작업 진행 가능
        # 작업을 진행 할 경우와 진행하지 않을 경우의 이익을 비교해서 큰 값으로 넣어줌
        dp[i] = max(dp[i+1], profits[i] + dp[i+times[i]])
                            # 작업을 진행 할 경우는 작업이익과 진행일수가 지난 시점의 이익을 더해줌

print(dp[0])

 

dp를 풀어본 기억이 좀 되어서인지 dp리스트에는 각 인덱스에 해당하는 정답을 넣어야만 한다고 생각했던게 문제였던 것 같다.

dp에는 "필요한 값"만 들어가면 되는 듯 하다.

'Algorithm > acmicpc.net' 카테고리의 다른 글

골드의 길은 멀고도 험하다  (0) 2022.01.20
스타트와 링크 링크와 스타트  (0) 2022.01.19
다음수열, 이전수열  (0) 2022.01.13
백트래킹 : M과 N, 순열  (0) 2022.01.11
백트래킹?  (0) 2022.01.09