티스토리 뷰
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 문제입니다.
주어진 입력에 대해 i + T 일에 돈이 들어온다고 생각하면 dp[i+T] = max(dp[i + T], current + P) 입니다.
왜냐하면 1번째 날부터 이어온다고 생각하면 현재 벌 수 있는 최대값 current와 i번째 날부터 일을 시작했을 때 버는 돈 P원의 합은 i+T일의 최대 수입은 current+P 또는 dp[i+T] 입니다. 이 때 n+1 일을 넘는 부분에 대해서는 계산을 하면 안 됩니다.
코드는 다음과 같습니다.
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int n, t, p;
int arr[1500002][2];
int dp[1500002];
void init()
{
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> t >> p;
arr[i][0] = t;
arr[i][1] = p;
}
memset(dp, 0, sizeof(dp));
}
// i 번 째 날 t 일 일 한 거 : i+t 일에 돈 들어온다고 생각
// dp[x] = max(dp[x], P_i + current) (i+t=x, current : 현재 최대 수입)
// n+1보다 큰 날은 계산 금지
int getResult() {
int result = 0;
int current = 0; // 현재 날 까지 최대값
for (int i = 1; i <= (n + 1); i++) {
int T = arr[i][0];
int P = arr[i][1];
int x = i + T;
current = max(current, dp[i]);
if (x > (n + 1)) {
result = max(result, current);
}
else {
dp[x] = max(dp[x], P + current);
result = max(result, current);
}
}
return result;
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
init();
cout << getResult();
}
'알고리즘 > 백준' 카테고리의 다른 글
백준 2210 숫자판 점프 C++ (0) | 2022.05.06 |
---|---|
백준 12904 A와 B C++ (0) | 2022.04.07 |
백준 3955 캔디 분배 C++ (0) | 2022.03.29 |
백준 16946 벽 부수고 이동하기 4 C++ (0) | 2022.03.18 |
백준 2668 숫자고르기 C++ (0) | 2022.03.15 |
댓글