백준이당
[C++] 백준 14501번 : 퇴사
이히당
2025. 5. 20. 22:15
문제
https://www.acmicpc.net/problem/14501
최대 수입을 가져갈 수 있도록 한다.
점화식
d[i] : i번째 날부터 퇴사일까지 벌 수 있는 최대 수입
i + day <= n : d[i] = max(d[i + day] + value, d[i + 1])
else : d[i] = d[i + 1]
즉, 가장 마지막날 시작하는 작업부터 ~ 첫날 시작하는 작업 순으로 확인하면서,
기존의 이벤트를 유지하는 게 더 효율적일지,
아니면 새 이벤트를 추가하는 것이 더 효율적일지를 확인한다.
만약, [ 작업 시작일 + 작업 소요 시간 ] > [ 퇴사일 ] 이라면, 수행할 수 없는 작업이므로,
(i+1)번 째 날부터 퇴사까지에 벌 수 있는 수입과 (i)번째 날부ㅌ 퇴사까지에 벌 수 있는 수입과 동일하게 된다.
만약, [ 작업 시작일 + 작업 소요 시간 ] <= [ 퇴사일 ] 이라면, 수행할 수 있는 작업이므로,
해당 작업을 추가했을 때의 수입과 추가하지 않았을 때의 수입을 비교하여 더 큰 수입을 가져갈 수 있도록 한다.
이때, 새로운 작업이 추가되는데, 작업은 수요시간이 들기 때문에, 그 만큼의 소요 시간을 여유로 둬야한다.
따라서, d[i] = max(d[i + day] + value, d[i + 1])
와 같은 점화식이 만들어지게 된 것이다.
풀이
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int n;
cin >> n;
vector<pair<int, int>> work;
for (int i = 0; i < n; i++)
{
int day, value;
cin >> day >> value;
work.push_back({day, value});
}
vector<int> d(n + 1, 0);
for (int i = n - 1; i >= 0; i--)
{
auto [day, value] = work[i];
// 만약 작업이 퇴사일까지 가능하다면
if (i + day <= n)
{
d[i] = max(d[i + day] + value, d[i + 1]);
}
else
{
// 만약 작업이 퇴사일 까지 불가능하다면
d[i] = d[i + 1];
}
}
cout << d[0];
}
728x90