문제 : https://www.acmicpc.net/problem/14501
14501번: 퇴사
첫째 줄에 백준이가 얻을 수 있는 최대 이익을 출력한다.
www.acmicpc.net
코드
N = int(input())
T = [0] * (N+1)
P = [0] * (N+1)
for i in range(1, N+1):
T[i], P[i] = map(int, input().split(" "))
# 격자 만들기
grid = [[0]*(N+1) for _ in range(N+1)] # row: 상담, column: 일
# 격자 채우기
for row in range(1, N+1):
time = T[row]
price = P[row]
for col in range(1, N+1):
previous = max(grid[row-1][col], grid[row][col-1])
if row+time-1 == col:
grid[row][col] = max(previous, price + grid[row-1][col-time])
else:
grid[row][col] = previous
print(grid[N][N])
해설
1일차 상담을 시작한다고 하면, T1=3 이므로 3일째에 상담이 끝나게 된다.
2일차 상담을 시작한다고 하면, T2=5 이므로 6일째에 상담이 끝나게 된다.
동적 프로그래밍을 활용하여 문제를 풀기 위해 격자를 그려보기로 했다.
격자를 그리기 위해 고려해야 할 것은 다음과 같다.
- 각 Cell에 넣을 값 (최적화 시키고자 하는 값)은 무엇인가? -> 최대 price
- 이 문제를 어떻게 하위 문제로 나눌 수 있는가? -> n-1, n-2...개의 상담이 있을 때 최대 price
- 격자의 축은 무엇인가? -> 각 상담과 날짜
문제의 제약 조건은 다음과 같다.
- 그림1에서의 상담 날짜가 겹치면 안된다. = 상담이 끝난 다음날에 새로운 상담을 할 수 있다.
- 어떠한 상담이든 지정된 날짜 (ex: 3일차의 상담은 3일)에만 시작할 수 있다.
상담이 끝난 다음날에 새로운 상담을 시작할 수 있으므로, 상담이 끝난 날을 기준으로 셀을 채울 수 있다.
상담 B는 6일째에 끝나기에 2행 6열에 들어갈 수 있다. 그리고 상담 A와 B는 동시에 할 수 없으므로 (기간이 겹침) 둘 중 price가 높은 상담을 선택해서 cell을 채운다.
상담 D에 대하여 T4=1, P4=20 이며, 상담 D는 4일째에 시작해서 4일째에 끝난다. 따라서 3일째에 끝나는 A와 같이 상담할 수 있다. 즉, [4일째 - 1일]에서의 최댓값 + 상담 D의 price 를 가질 수 있으며, 이를 수식으로 나타내면 P4 + grid[ i-1 ][ j-T4] 이다.
이를 일반화시켜 격자를 채워보면 다음과 같이 나온다.
우리는 상담G까지 있을 때 7일째의 최댓값을 찾고자하므로, grid[7][7]의 값을 출력하면 된다.
'알고리즘 풀기' 카테고리의 다른 글
[백준] 2667 단지번호붙이기 python3 (0) | 2020.03.10 |
---|---|
[백준] 1967 트리의 지름 python3 (0) | 2020.03.10 |
[백준] 2875 대회or인턴 python3 (0) | 2020.02.29 |
[백준] 1414 불우이웃돕기 python3 (0) | 2020.02.29 |