다이나믹 프로그래밍
[백준/C++][퇴사2(15486번)]
산기대 컴공
2020. 12. 17. 22:47
728x90
문제
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
문제 풀이
일단 크게 두가지 경우로 나뉜다.
1. 시간이 초과되서 상담을 그날 상담을 못하는 경우
2. 시간이 초과되지 않아서 그날에 상담을 할 수 있는 경우
일단 1번의 경우이다.
상담을 한다면 N보다 초과되어서 이날의 상담은 하지 못하므로 이날의 최대 dp의 값은 i+1의 값이 된다. -> 이날 상담을 안하고 다음 날 한다.
2번의 경우
1.상담을 할 수 있으므로 상담을 하는 경우
2.상담을 안하는 경우
이렇게 또 2가지 경우로 나뉜다.
1번 경우는 상담을 하고 그날의 상담일당 + i+T날의 dp값이 1번의 값이다. -> dp[i+T]값은 그날의 최선의 값이기 때문에 가능.
2번의 경우는 상담을 안함으로 dp[i+1]이 값이 된다.
dp[i] = max(dp[i+1],dp[i+T]+v[i].second) 라는 점화식을 얻을 수 있다.
코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #include <iostream> #include <vector> #include <algorithm> #include <stdio.h> using namespace std; int N; int main(void){ int dp[1500001],result = -1; vector<pair<int,int>> v; v.push_back({0,0}); cin >> N; for(int i = 0;i<N;i++){ int a,b; scanf("%d%d",&a,&b); dp[i+1] = 0; v.push_back({a,b}); //시간,가치 } for(int i = N;i>=0;i--){ int T = v[i].first; if(i+T>N+1){ dp[i] = dp[i+1]; result = max(result,dp[i]); } else{ dp[i] = max(dp[i+1],v[i].second+dp[i+T]); result = max(result,dp[i]); } } cout << result; } | cs |
728x90