티스토리 뷰

DS\Algo

BOJ 15486 퇴사 2

MathTrauma 2022. 10. 9. 09:50

 

문제 링크 : 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. 여기서는 dp[i] 를 ( i-1 ) 번째 일까지 끝난 상담에 대한 금액의 최댓값으로 정의한다. 

(현실에서는 선불로 받는다 하더라도)

 

2. dp[i] 은 최소한 dp[i-1] 을 물려받는다.

수익은 기본적으로 누적 개념이므로 그 전날까지 벌어들인 금액은 그 다음 날에 포함되어야 한다.

 

#include<bits/stdc++.h>

using namespace std;
const int MaxN=1500002;

int dur[MaxN],cst[MaxN], dp[MaxN];

int main(){
    int n; scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d%d",&dur[i],&cst[i]);
    
    for(int i=1;i<=n;i++){
        dp[i+1]=max(dp[i],dp[i+1]);
        int x=i+dur[i];
        if(x<=n+1) dp[x]=max(dp[x], dp[i]+cst[i]);
    }
    
    printf("%d\n", dp[n+1]);
}

 

이번에는 탑다운 방식으로 해결해 보자.

아래 코드에서 dp[i] 는 i 번째 날부터 퇴사할 때까지 최대의 수익이다.(bottom up 과 방향이 반대)

 

#include<bits/stdc++.h>

using namespace std;
const int MaxN=1500002;

int N, dur[MaxN], cst[MaxN], dp[MaxN];

int recur(int i){
    if(i==N+1) return 0;
    int &ret=dp[i];
    if(ret!=-1) return ret;
    
    ret=0;
    ret=max(ret, recur(i+1));
    if(i+dur[i]<=N+1)
        ret=max(ret,cst[i]+recur(i+dur[i]));
    return ret;
}

int main(){
    scanf("%d",&N);
    memset(dp, -1, sizeof dp);
    
    for(int i=1;i<=N;i++)
        scanf("%d%d",&dur[i],&cst[i]);
    
    printf("%d\n", recur(1));
}

 

 

 

반응형

'DS\Algo' 카테고리의 다른 글

BOJ 1562 계단 수  (0) 2022.10.12
BOJ 14698 전생했더니 슬라임 연구자였던 건에 대하여 (Hard)  (0) 2022.10.10
BOJ 5735 Emoticons :-)  (0) 2022.10.08
BOJ 10256 Mutation( 돌연변이 )  (0) 2022.10.07
BOJ 13398 연속합 2  (0) 2022.10.07
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
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 31
글 보관함