[풀이]
처음에 많이 헤맸지만.. 결국 각 마을 마다 실을 수 있는 공간을 체크해나가며 해결할 수 있는 문제였습니다.
문제를 해결하기 위해선 우선 도착지를 기준으로 오름차순 정렬 해주어야 합니다. 출발지는 상관 없습니다.
왜 그런지는 이 후에 제가 설명드리는 과정을 보면 이해할 수 있을 겁니다:)
1. 출발지부터 도착지 - 1 까지에서 트럭 잔여용량이 가장 적은 곳 찾기
2. 실을 박스의 수 정하기 (1에서 찾은 잔여용량보다 박스의 수가 많다면 1에서의 결과값만큼 박수 싣기)
3. 출발지부터 도착지 - 1 까지 실을 박수의 수만큼 잔여용량을 줄여주기
이렇게 3가지를 차례대로 반복해줍니다.
문제상의 예제를 바탕으로 풀이해보겠습니다.
마을 | 1 | 2 | 3 |
잔여용량 | 40 | 40 | 40 |
우선, 초기상태 입니다. 마을은 4까지 있지만 4는 어짜피 도착지이니 표기할 필요가 없어서 3까지만 표기하였습니다.
그리고 각 마을에서의 트럭 잔여용량을 전부 최대치로 초기화 해놓습니다.
배송할 목록을 도착지를 기준으로 오름차순 정렬하면 다음과 같겠죠??
1 2 10
1 3 20
2 3 10
1 4 30
2 4 20
3 4 20
이를 바탕으로 위에서부터 차례대로 써먹습니다!! ㅎㅎ
마을 | 1 | 2 | 3 |
잔여용량 | 40 - 10 = 30 | 40 | 40 |
1 2 10
1. 마을 1 <= x < 2에서 제일 적은 잔여용량은 40.
2. 실을 용량(10) < 잔여용량(40) 이므로 전량(10) 싣기.
3. 마을 1 <= x < 2 까지 실은 박스 수만큼 빼주기.
--> 현재까지 운반한 박스 수 = 10
마을 | 1 | 2 | 3 |
잔여용량 | 30 - 20 = 10 | 40 - 20 = 20 | 40 |
1 3 20
1. 마을 1 <= x < 3에서 제일 적은 잔여용량은 30.
2. 실을 용량(20) < 잔여용량(30) 이므로 전량(20) 싣기.
3. 마을 1 <= x < 3 까지 실은 박스 수만큼 빼주기.
--> 현재까지 운반한 박스 수 = 30
마을 | 1 | 2 | 3 |
잔여용량 | 10 | 20 - 10 = 10 | 40 |
2 3 10
1. 마을 2 <= x < 3에서 제일 적은 잔여용량은 20.
2. 실을 용량(10) < 잔여용량(20) 이므로 전량(10) 싣기.
3. 마을 2 <= x < 3 까지 실은 박스 수만큼 빼주기.
--> 현재까지 운반한 박스 수 = 40
마을 | 1 | 2 | 3 |
잔여용량 | 10 - 10 = 0 | 10 - 10 = 0 | 40 - 10 = 30 |
1 4 30
1. 마을 1 <= x < 4에서 제일 적은 잔여용량은 10.
2. 실을 용량(30) > 잔여용량(10) 이므로 일부분(10) 싣기.
3. 마을 1 <= x < 4 까지 실은 박스 수만큼 빼주기.
--> 현재까지 운반한 박스 수 = 50
마을 | 1 | 2 | 3 |
잔여용량 | 0 | 0 | 30 |
2 4 20
1. 마을 2 <= x < 4에서 제일 적은 잔여용량은 0
2. 용량 0이므로 옮길 박스가 없음.
--> 현재까지 운반한 박스 수 = 50
마을 | 1 | 2 | 3 |
잔여용량 | 0 | 0 | 30 - 20 = 10 |
3 4 20
1. 마을 3 <= x < 4에서 제일 적은 잔여용량은 20.
2. 실을 용량(20) < 잔여용량(30) 이므로 전량(20) 싣기.
3. 마을 3 <= x < 4 까지 실은 박스 수만큼 빼주기.
--> 현재까지 운반한 박스 수 = 70
이러한 프로세스로 정답은 70!!
만약 도착지가 내림차순이거나 뒤죽박죽이라면 절대 이렇게 진행할 수가 없습니다.
만약 총 용량 40,
1 5 10
2 3 40
3 4 40
이런 배송지가 있고 이순서대로 진행한다하면 답은 70이겠지만
올바른 답은 마을 2와 3에서 40번씩 옮길 수 있어서 답은 80이 되겠죠?
이처럼 중간에 있는 마을들이 어떨지 알 수 없기 때문에 도착지를 기준으로 오름차순 필수!
아래는 풀이한 코드입니다 :)
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
56
57
|
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Delivery {
public:
int from;
int to;
int cnt;
Delivery(int from, int to, int cnt) {
this->from = from;
this->to = to;
this->cnt = cnt;
}
};
// 도착지 기준 오름차순 정렬!
bool cmp(Delivery a, Delivery b) {
if (a.to < b.to) return true;
else return false;
}
int main(void) {
int n, c, m;
cin >> n >> c >> m;
vector<Delivery> list;
vector<int> left(n + 1, c);
int box_cnt = 0;
for (int i = 0; i < m; i++) {
int from, to, cnt;
cin >> from >> to >> cnt;
list.push_back(Delivery(from, to, cnt));
}
sort(list.begin(), list.end(), cmp);
for (auto d : list) {
// 제일 공간이 적게 남은 개수 찾기
int min = left[d.from];
for (int i = d.from + 1; i < d.to; i++) {
if (min > left[i]) min = left[i];
}
// 실을 박스의 수(만약 min보다 많다면 min만큼만 싣기)
int cnt = d.cnt;
if (min < cnt) cnt = min;
// 최종 박스 수에 +
box_cnt += cnt;
// from ~ to - 1 까지 cnt만큼 빈공간 줄이기
for (int i = d.from; i < d.to; i++) {
left[i] -= cnt;
}
}
cout << box_cnt;
return 0;
}
|
cs |
질문이나 지적사항은 댓글 부탁드립니다:)
'알고리즘 > BOJ' 카테고리의 다른 글
[백준] 2816번 디지털 티비 (0) | 2019.08.27 |
---|---|
[백준] 3109번 빵집 (0) | 2019.08.19 |
[백준] 1543번 문서 검색 (0) | 2019.07.30 |
[백준] 1202번 보석도둑 (0) | 2019.07.26 |
[백준] 1969번 DNA (0) | 2019.07.18 |