[백준 8980번 C/C++] 택배
[백준 8980번 C/C++] 택배

https://www.acmicpc.net/problem/8980
8980번: 택배
입력의 첫 줄은 마을 수 N과 트럭의 용량 C가 빈칸을 사이에 두고 주어진다. N은 2이상 2,000이하 정수이고, C는 1이상 10,000이하 정수이다. 다음 줄에, 보내는 박스 정보의 개수 M이 주어진다. M은 1이
www.acmicpc.net
해결전략
그리디 Greedy Algorithm
- 각 택배를 가능한 한 먼저 배달해야 하는 목적지 마을 순으로 정렬.
- 각 마을별 남은 용량 계산
- 트럭이 각 마을을 방문할 때마다 특정 용량만큼의 박스를 싣고 내린다.
- 이를 관리하기 위해 capacity 벡터를 사용하여 각 마을별로 남은 용량을 관리한다. 초기값은 트럭의 최대 용량인 c로 설정한다.
- 택배 배달
- 각 택배에 대해 시작 마을부터 목적지 마을까지의 경로에 대해 현재 남아 있는 최소 용량을 찾는다.
- 해당 택배가 이 경로를 거치며 최대로 실을 수 있는 박스의 수를 결정한다.
- 이 최소 용량(minCap)과 택배의 박스 수(v[i].box) 중 더 작은 값이 실제로 이번에 실을 수 있는 박스의 수(canLoad)가 된다.
- 이 canLoad만큼 각 마을의 capacity를 감소시킨다.
- answer에도 canLoad를 더하여 최종적으로 배달할 수 있는 박스의 총 개수를 계산한다.
각 택배를 운반하는 과정에서 경로 상의 모든 마을에서 남은 용량 중 최소값을 찾아 그만큼만 운반 시킨다.
핵심 아이디어
- 효율적인 배달 순서: 목적지 마을 번호가 낮은 순서대로 택배를 정렬하고 배달함으로써, 트럭의 이동 경로를 최적화하고, 중간에 다른 택배를 추가로 실을 수 있는 기회를 최대화한다.
- 경로 상의 최소 용량을 기준으로 택배를 싣는 방법: 각 마을별로 남은 용량을 최적으로 관리하면서, 가능한 많은 택배를 목적지까지 운반할 수 있다.
정답코드
#include <iostream> #include <vector> #include <algorithm> using namespace std; int n, c; // n: 마을의 수, c: 트럭의 용량 int m; // m: 보내는 박스의 개수 int answer; // 최종적으로 배달할 수 있는 박스의 총 개수 struct Info { int start, end, box; // 시작 마을, 목적 마을, 택배의 박스 개수 Info(int a, int b, int c) { start = a; end = b; box = c; } // 목적 마을이 낮은 순으로 정렬! 그 다음에 시작 마을 낮은 순 정렬 bool operator<(const Info& oper) { if (end == oper.end) { start < oper.start; } return end < oper.end; } }; vector<Info> v; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> n >> c >> m; for (int i = 0; i < m; i++) { int a, b, c; cin >> a >> b >> c; v.push_back({ a, b, c }); } sort(v.begin(), v.end()); // 목적 마을이 낮은 순으로 정렬! 그 다음에 시작 마을 낮은 순 정렬 vector<int> capacity(n + 1, c); // 각 마을별 남은 용량. 기본값 최대 용량인 c로 설정 for (int i = 0; i < v.size(); i++) { // 시작 마을부터 목적지 마을까지의 경로에서 현재 남아 있는 최소 용량을 찾는다. // 이 최소 용량과 해당 택배의 박스 개수 중 더 작은 값이 이번에 실을 수 있는 박스의 수(canLoad)가 된다. int minCap = c; for (int j = v[i].start; j < v[i].end; j++) { minCap = min(minCap, capacity[j]); } // 시작 마을부터 목적지 마을 전까지의 각 마을의 남은 용량을 canLoad만큼 감소시킨다. // 해당 택배가 해당 경로를 거치며 운반되고 있음 int canLoad = min(minCap, v[i].box); for (int j = v[i].start; j < v[i].end; j++) { capacity[j] -= canLoad; } answer += canLoad; } cout << answer; return 0; }
'⭐ 코딩테스트 > 백준' 카테고리의 다른 글
[백준 3687번 C/C++] 성냥개비 (0) | 2024.04.14 |
---|---|
[백준 14890번 C/C++] 경사로 (0) | 2024.04.13 |
[백준 24337번 C/C++] 가희와 탑 (0) | 2024.04.09 |
[백준 2931번 C/C++] 가스관 (1) | 2024.04.08 |
[백준 17825번 C/C++] 주사위 윷놀이 (0) | 2024.04.03 |
댓글
이 글 공유하기
다른 글
-
[백준 3687번 C/C++] 성냥개비
[백준 3687번 C/C++] 성냥개비
2024.04.14 -
[백준 14890번 C/C++] 경사로
[백준 14890번 C/C++] 경사로
2024.04.13 -
[백준 24337번 C/C++] 가희와 탑
[백준 24337번 C/C++] 가희와 탑
2024.04.09 -
[백준 2931번 C/C++] 가스관
[백준 2931번 C/C++] 가스관
2024.04.08
댓글을 사용할 수 없습니다.