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 문제
1부터 n까지 순회하면서 현재까지의 최댓값을 저장해둔다.
dp[n]은 n일까지 일했을 때 얻을 수 있는 최대 수익으로
i번째 날에 들렸을 때, 현재까지 얻을 수 있는 최댓값과 그 날에 저장된 값을 비교하여 갱신하여 주고,
i번째 날에 일했을 때 얻을 수 있는 최대 수익을 i번째 일했을 때 수익을 얻는 날(i + 해당 일의 소요 날짜) dp 배열에 값을 갱신하여 준다.
#include <stdio.h>
#include <algorithm>
#define MAX 1500001
using namespace std;
FILE* in = fopen("input.txt", "r");
int n;
int time[MAX];
int money[MAX];
int cache[MAX];
int curr_max;
//cache[n]은 n일까지 일했을 때의 최대 수익
void dp(int idx) {
//현재까지의 최대 수익과 cache[n] 값을 비교해준 뒤 갱신
curr_max = max(curr_max, cache[idx]);
//idx가 n을 넘어가면 런타임 오류가 뜨기 때문에 조건문에서 선제적으로 처리
//idx+time[idx]는 n번째의 갱신하기 때문에 등호를 붙여준다.
if(idx < n && idx + time[idx] <= n)
cache[idx + time[idx]] = max(curr_max + money[idx], cache[idx + time[idx]]);
// 갱신
cache[idx] = curr_max;
return;
}
int main() {
fscanf(in, "%d", &n);
for (int i = 0; i < n; i++)
{
fscanf(in, "%d %d", &time[i], &money[i]);
}
// 0부터 n까지 순회
for (int i = 0; i <= n; i++)
dp(i);
printf("%d", cache[n]);
}
'알고리즘 > 백준' 카테고리의 다른 글
백준 12865번 평범한 배낭 C/C++ 풀이 (0) | 2020.08.19 |
---|---|
백준 2228번 구간 나누기 C/C++ 풀이 (0) | 2020.08.18 |
백준 5535번 패셔니스타 C/C++ 풀이 (0) | 2020.08.17 |
백준 2240번 자두나무 C/C++ 풀이 (0) | 2020.08.17 |
백준 5557번 1학년 C/C++ 풀이 (0) | 2020.08.17 |