Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
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
Archives
Today
Total
관리 메뉴

개발하지연

[백준 15486번] 퇴사 2 (python) 본문

알고리즘

[백준 15486번] 퇴사 2 (python)

JeongJiyeon 2021. 7. 29. 00:19

문제

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

오늘부터 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이다.

상담을 적절히 했을 때, 백준이가 얻을 수 있는 최대 수익을 구하는 프로그램을 작성하시오.

 

기록

(dp 7일차) 올림픽에 빠져서 며칠 문제만 풀고 글을 못올렸다. 다시 열심히 써보자! 처음에 dp배열에서 바로 앞의 원소와 비교한다는 걸 생각못하고 앞의 원소들 중 max 찾아서 비교하도록 했더니 시간초과났다.

 

이 문제는 각 날짜에서의 최대 수익을 dp배열을 생성하여, dp[종료일] = max(이전까지의 수익+현재 수익, dp[종료일])을 계산함과 동시에 이전 날짜와 현재 날짜를 비교하여 순차적으로 최댓값을 저장한다. 과정은 아래와 같다.

 

1일차의 상담, T=3, P=10. 

0 1 2 3 4 5 6 7
0 0 0 10 0 0 0 0

이전수익과 현재수익이 같으므로 그대로 dp[1]=0.

1일차의 상담(dp[0]+10) > 종료일 수익(dp[3]) 이므로 dp[3] 수정.

 

2일차의 상담, T=5, P=20.  1 10 1 20 2 15

0 1 2 3 4 5 6 7
0 0 0 10 0 0 20 0

이전수익과 현재수익이 같으므로 그대로 dp[2]=0.

2일차의 상담(dp[1]+20) > 종료일 수익(dp[6]) 이므로 dp[6]=20.

 

3일차의 상담, T=1, P=10.  1 20 2 15

0 1 2 3 4 5 6 7
0 0 0 10 0 0 20 0

이전수익보다 현재수익이 크므로 그대로 dp[3]=10.

3일차의 상담(dp[2]+10) = 종료일 수익(dp[3]) 이므로 dp[3] 그대로.

 

4일차의 상담, T=1, P=20.  2 15

0 1 2 3 4 5 6 7
0 0 0 10 30 0 20 0

이전수익이 현재수익보다 크므로 dp[4]=10.

4일차의 상담(dp[3]+20) > 종료일 수익(dp[4]) 이므로 dp[4]=30.

 

5일차의 상담, T=2, P=15.

0 1 2 3 4 5 6 7
0 0 0 10 30 30 45 0

이전수익이 현재수익보다 크므로 dp[5]=30.

5일차의 상담(dp[4]+15) > 종료일 수익(dp[6]) 이므로 dp[6]=45.

 

6일차의 상담, T=4, P=40.

0 1 2 3 4 5 6 7
0 0 0 10 30 30 45 0

이전수익이 현재수익보다 작으므로 dp[6] 그대로.

6일차의 상담 종료일은 N을 벗어났기 때문에 아무일 없음.

 

7일차의 상담, T=2, P=200.

0 1 2 3 4 5 6 7
0 0 0 10 30 30 45 45

이전수익이 현재수익보다 크므로 dp[7]=45.

7일차의 상담 종료일은 N을 벗어났기 때문에 아무일 없음.

 

코드

from sys import stdin

N = int(stdin.readline())
dp = [0]*(N+1)
for i in range(1, N+1):
    t, p = map(int, stdin.readline().split())
    dp[i] = max(dp[i-1], dp[i])
    if i+t<=N+1:
        dp[i+t-1] = max(dp[i-1]+p, dp[i+t-1])

print(dp[-1])

1. 각 날짜의 최대 수익 저장할 dp배열 생성

2. 1일차부터 순차적으로 dp[i-1]와 비교하여 현재 날짜의 최댓값 갱신, 동시에 상담 종료일의 최댓값도 갱신한다.

3. 마지막 날짜의 최대수익 출력

Comments