코딩테스트
[백준] 퇴사2 파이썬 DP
_maddy
2024. 3. 22. 01:40
https://www.acmicpc.net/problem/15486
15486번: 퇴사 2
첫째 줄에 N (1 ≤ N ≤ 1,500,000)이 주어진다. 둘째 줄부터 N개의 줄에 Ti와 Pi가 공백으로 구분되어서 주어지며, 1일부터 N일까지 순서대로 주어진다. (1 ≤ Ti ≤ 50, 1 ≤ Pi ≤ 1,000)
www.acmicpc.net
내 첫 DP 문제... 어렵다 어려워... 처음에 DP라는 걸 모르고 그냥 풀었다가 시간초과나서 이게 뭐지 싶었음.
<DP를 몰랐을 때 쌩구현 코드>
더보기
#퇴사2 DP - 내가 dp를 몰랐을 때.
n=int(input())
day=0
total=0
t=[]
p=[]
for i in range(n):
T,P=map(int,input().split())
t.append(T)
p.append(P)
max_pay=0
for i in range(n):
day=i+1 #0+1=1, 4, 5
total=0
while True:
if day+t[day-1]<n+1:
total+=p[day-1] #p[0]=10, total=10
day+=t[day-1] #t[0]=3, day=3,[3]=1
elif day+t[day-1]==n+1:
total+=p[day-1] #p[0]=10, total=10
#day+=t[day-1] #t[0]=3, day=3,[3]=1
break
else:
break
if max_pay<total:
max_pay=total
print(max_pay)
이렇게 푸니 시간초과가 나왔다.
<DP를 알고 난 뒤 코드 - 구글링을 통해 해결>
#퇴사 dp 2번째 시도
import sys
input=sys.stdin.readline
N=int(input())
dp=[0 for i in range(N+1)]
#0,1,2,3,4,5,6
for i in range(N):
t,p=map(int,input().split())
dp[i+1]=max(dp[i+1],dp[i])
if i+t<N+1:
dp[i+t]=max(dp[i+t],dp[i]+p)
print(dp[-1])
처음에 sys.stdin.readline을 쓰지 않았다가 또 시간초과가 되었다... 파이썬으로 시간초과 피하기란 쉽지 않다. 위의 코드를 이해하는데도 한참 걸렸다.
<과정>
- 우선, sys.stdin.readline() 함수를 사용하여 한 줄씩 입력을 받는다. 이 함수는 빠른 입력을 처리하기 위해 사용된다.
- 첫 번째 입력으로는 일의 개수 N을 받는다.
- 그 다음 N개의 줄에는 걸리는 일수, 금액을 입력.
- 이후에는 N일 동안의 최대 수익을 저장하기 위한 리스트인 dp를 초기화합니다. dp[i]는 i일까지의 최대 수익을 나타낸다.
- 반복문을 통해 각 날짜에 대해 최대 수익을 갱신해 나갑니다. 각 날짜에 대해 두 가지 경우를 고려.
- 해당 날짜를 포함하지 않을 경우(dp[i]) : 이전 날짜의 최대 수익과 동일. 이전 날짜 까지의 최대 이익이다. 다시 말해 현재 날짜에 일을 하지 않고 이전 날짜 까지의 최대 이익을 의미.
- 해당 날짜를 포함할 경우(dp[i+t]) : 해당 날짜에 일을 수행하고 수행 완료된 날짜(i+t)까지의 최대 수익과 해당 일을 마치고 얻을 수 있는 수익(p)을 더한다. 혀냊 날짜를 포함해 일을 수행할 경우의 최대 이익을 의미, 현재 날짜부터 t일 동안의 작업을 수행하고 그 일을 마치면 얻을 수 있는 이익을 현재 날짜부터 t일 동안의 최대 이익에 더한 값.
- 모든 날짜에 대해 최대 수익을 갱신한 후, 마지막 날의 최대 수익인 dp[-1]을 출력