Skip to content

Commit

Permalink
content: programmers 택배 배달과 수거하기
Browse files Browse the repository at this point in the history
  • Loading branch information
loopy-dev committed Oct 2, 2023
1 parent c1ef8e2 commit 23b04e9
Showing 1 changed file with 69 additions and 0 deletions.
69 changes: 69 additions & 0 deletions content/ps/e1x93vDwfxPtmwEMRhweR.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
title: 프로그래머스 - 택배 배달과 수거하기(python)
createdTime: 2023-10-02
tags:
- 프로그래머스
- 레벨2
- python
- priority queue
description: 프로그래머스 택배 배달과 수거하기 문제 풀이
---

## 택배 배달과 수거하기

당신은 일렬로 나열된 `n`개의 집에 택배를 배달하려 합니다. 배달할 물건은 모두 크기가 같은 재활용 택배 상자에 담아 배달하며, 배달을 다니면서 빈 재활용 택배 상자들을 수거하려 합니다.

배달할 택배들은 모두 재활용 택배 상자에 담겨서 물류창고에 보관되어 있고, `i`번째 집은 물류창고에서 거리 `i`만큼 떨어져 있습니다. 또한 `i`번째 집은 `j`번째 집과 거리 `j - i` 만큼 떨어져 있습니다. (1 ≤

`i``j``n`)

트럭에는 재활용 택배 상자를 최대 `cap`개 실을 수 있습니다. 트럭은 배달할 재활용 택배 상자들을 실어 물류창고에서 출발해 각 집에 배달하면서, 빈 재활용 택배 상자들을 수거해 물류창고에 내립니다. 각 집마다 배달할 재활용 택배 상자의 개수와 수거할 빈 재활용 택배 상자의 개수를 알고 있을 때, 트럭 하나로 모든 배달과 수거를 마치고 물류창고까지 돌아올 수 있는 최소 이동 거리를 구하려 합니다.

**각 집에 배달 및 수거할 때, 원하는 개수만큼 택배를 배달 및 수거할 수 있습니다.**

### 링크

[](https://school.programmers.co.kr/learn/courses/30/lessons/150369)

**[ 문제에 대한 이해 ]**

1. 일열로 나열된 n개의 집에 택배를 배달한다.
2. 트럭에 실을 수 있는 택배상자의 개수는 최대 cap개이고, 각 집에 배달함과 동시에 빈 상자를 수거할 수 있다.
3. 모든 배달과 수거를 마치고 물류창고까지 돌아올 수 있는 **최소** 거리를 구한다.


### 어떤 칸에서부터 시작해야 할까?

모르면 일단 아무 지점에서 사이클을 만들어보자. → 모든 지점에서 완전 탐색을 해보자.

- 참고로, 사이클 특성 상 가장 첫 번째 위치에서만 탐색을 하더라도 모든 사이클의 파악이 가능하다. 모든 지점, 모든 방향에 대해 방문할 수 있다.
- 동일한 사이클의 기준
- y, x 좌표에서 d 방향으로 이동한 이력이 있다면, 이미 사이클이 만들어졌다는 뜻이므로 더 이상 탐색할 필요가 없다.
- 해당 지점에서 SLR에 따른 방향으로 이동할 경우 뒤 이동 경로는 동일하기 때문이다.

## 접근 방법

### 어떤 방식으로 풀 수 있는가

우선 문제의 조건에서 총 배열의 길이가 10만까지 주어질 수 있다고 했으므로, 완전 탐색으로 해결은 불가능하다. 몇 번의 순회과정을 거쳐야 하는지도 알 수 없으며 그 과정에서 걸리는 시간 또한 예측이 불가능하기 때문이다.

> 그리디 방식으로 최적의 해를 구할 수 있는지 확인한다.
>
우선 문제의 접근 방식을 따른다. 문제에서는 택배를 수거할 때 물류센터에서부터 가장 먼 곳의 택배부터 배달을 시작했다(최대로 실을 수 있을 때까지의 인덱스에서부터 시작한다). 그렇기 때문에 뒤에서 부터 순회하면서 채울 수 있는 최대의 개수만큼 채우고, 빈 박스 역시 마찬가지의 방법으로 수거하면서 물류센터로 돌아가면 된다.

### 우선순위 큐로 접근하기

배열을 뒤에서부터 순회하면서 2번 순회하여 문제를 해결할 수 있을 수도 있지만, 이번 해결 방식에서는 우선순위 큐를 이용하였다.

1. 우선순위 큐를 이용하여 가장 높은 인덱스부터 꺼내서 확인
2. distance의 최댓값을 저장하기
3. current_amount의 양 + 현재 인덱스의 값이 cap보다 작거나 같다면 값을 더하기
1. 그렇지 않다면 순회를 멈추고 총 cap에서 뺀 값을 다시 우선순위 큐에 집어넣기
4. 로직을 수거 시에도 적용하고, 저장한 최댓값에 * 2를 해서 total에 더하기
5. 큐에 모든 요소가 없을 때까지 반복하기


## 통과 코드

<div data-gist="d805c18b1e628098fae2a5b46d393356"></div>

0 comments on commit 23b04e9

Please sign in to comment.