Algorithm/BOJ

[백준 1826] 연료 채우기 (C++)

Henu 2021. 11. 1. 15:40
 

1826번: 연료 채우기

첫째 줄에 주유소의 개수 N(1 ≤ N ≤ 10,000)가 주어지고 두 번째 줄부터 N+1번째 줄 까지 주유소의 정보가 주어진다. 주유소의 정보는 두개의 정수 a,b로 이루어 져 있는데 a(1 ≤ a ≤ 1,000,000)는 성경

www.acmicpc.net

 

처음에 DP 문제인줄 알고 DP로 접근을 시도했었다.

dp[현재 이동한 거리][현재 가지고 있는 연료 양] 을 두면 top down DP를 통해서 쉽게 구할 수 있을거라고 생각했었다.

근데 L이 최대 100만이고 연료 양도 최대 100*10000 라서 DP 배열 자체를 할당할 수가 없었다.

 

N과 L이 너무 커서 이건 무조건 그리디라고 생각했고 실제로 그리디로 풀수가 있었다.

 

 

1. 현재 연료를 모두 소진할 때까지 쭉 달린다.

2. 달리는 도중에 주유소를 만나면 priority queue에 저장한다.(최대 힙으로 저장)

3. 연료를 모두 소진하면 priority queue에서 연료를 가져와서 보충한다.

-> 주유소에 들릴때 바로 연료를 충전하지 않고 keep 해놓았다가 나중에 필요할 때 가져오는 방식을 사용한다. 이때 주유소에 들리는 카운터를 +1 해준다.

 

4. 만약 현재 연료가 0가 되었고, priority queue에 저장해 놓은 연료 리스트가 없다면 목표에 도달할 수 없는 것이므로 -1을 출력한다.

 

 

 

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#define fastio ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
 
using namespace std;
 
int N, L, P;
int info[1000001];
 
void input(){
    cin >> N;
    int a, b;
    for(int i = 0; i < N; i++){
        cin >> a >> b;
        info[a] = b;
    }
    cin >> L >> P;
    
}
 
void solve(){
    priority_queue<int> pq;
    int now_fuel = P;
    int ans = 0;
    
    for(int i = 1; i < L; i++){
        now_fuel--;
        if(info[i]) pq.push(info[i]);
        
        if(!now_fuel){
            if(pq.empty()){
                cout << -1;
                return;
            }
            else{
                ans++;
                now_fuel += pq.top();
                pq.pop();
            }
        }
    }
    
    cout << ans;
}
 
int main(){
    fastio
    input();
    solve();
    
    return 0;
}
 
cs