Coding Is My Life

코딩은 인생

다이나믹 프로그래밍

[백준/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