티스토리 뷰
목차
문제
어떤 나라에 N개의 도시가 있다.
이 도시들은 일직선 도로 위에 있다.
편의상 일직선을 수평 방향으로 두자.
제일 왼쪽의 도시에서 제일 오른쪽의 도시로 자동차를 이용하여 이동하려고 한다.
인접한 두 도시 사이의 도로들은 서로 길이가 다를 수 있다.
도로 길이의 단위는 km를 사용한다.
처음 출발할 때 자동차에는 기름이 없어서 주유소에서 기름을 넣고 출발하여야 한다.
기름통의 크기는 무제한이어서 얼마든지 많은 기름을 넣을 수 있다.
도로를 이용하여 이동할 때 1km마다 1리터의 기름을 사용한다.
각 도시에는 단 하나의 주유소가 있으며, 도시마다 주유소의 리터당 가격은 다를 수 있다.
가격의 단위는 원을 사용한다.
예를 들어, 이 나라에 다음 그림처럼 4개의 도시가 있다고 하자.
원 안에 있는 숫자는 그 도시에 있는 주유소의 리터당 가격이다.
도로 위에 있는 숫자는 도로의 길이를 표시한 것이다.
제일 왼쪽 도시에서 6리터의 기름을 넣고, 더 이상의 주유 없이 제일 오른쪽 도시까지 이동하면 총비용은 30원이다.
만약 제일 왼쪽 도시에서 2리터의 기름을 넣고(2×5 = 10원) 다음번 도시까지 이동한 후 3리터의 기름을 넣고(3×2 = 6원)
다음 도시에서 1리터의 기름을 넣어(1×4 = 4원) 제일 오른쪽 도시로 이동하면, 총비용은 20원이다.
또 다른 방법으로 제일 왼쪽 도시에서 2리터의 기름을 넣고(2×5 = 10원)
다음번 도시까지 이동한 후 4리터의 기름을 넣고(4×2 = 8원) 제일 오른쪽 도시까지 이동하면, 총비용은 18원이다.
각 도시에 있는 주유소의 기름 가격과, 각 도시를 연결하는 도로의 길이를 입력으로 받아
제일 왼쪽 도시에서 제일 오른쪽 도시로 이동하는 최소의 비용을 계산하는 프로그램을 작성하시오.
입력
표준 입력으로 다음 정보가 주어진다. 첫 번째 줄에는 도시의 개수를 나타내는 정수 N(2 ≤ N ≤ 100,000)이 주어진다.
다음 줄에는 인접한 두 도시를 연결하는 도로의 길이가 제일 왼쪽 도로부터 N-1개의 자연수로 주어진다.
다음 줄에는 주유소의 리터당 가격이 제일 왼쪽 도시부터 순서대로 N개의 자연수로 주어진다.
제일 왼쪽 도시부터 제일 오른쪽 도시까지의 거리는 1 이상 1,000,000,000 이하의 자연수이다.
리터당 가격은 1 이상 1,000,000,000 이하의 자연수이다.
출력
표준 출력으로 제일 왼쪽 도시에서 제일 오른쪽 도시로 가는 최소 비용을 출력한다.
서브태스크
번호 | 배점 | 제한 |
1 | 17 | 모든 주유소의 리터당 가격은 1원이다. |
2 | 41 | 2 ≤ N ≤ 1,000, 제일 왼쪽 도시부터 제일 오른쪽 도시까지의 거리는 최대 10,000, 리터 당 가격은 최대 10,000이다. |
3 | 42 | 원래의 제약조건 이외에 아무 제약조건이 없다. |
풀이
그리디 알고리즘 단계의 마지막 문제이다.
문제가 길지만 요약하면 일렬로 나열된 도시와 각 도시의 리터당 가격이 주어졌을 때
가장 왼쪽 도시에서 가장 오른쪽 도시까지 이동하는데 필요한 기름값의 최소를 구하는 문제이다.
알고리즘 역시 매우 단순해 굳이 요약할 필요가 있나 싶긴 하지만, 요약해 보면 다음과 같은 순서로 풀어나간다.
- 첫 번째 도시에서 두 번째 도시까지 이동하는 기름값은 변하지 않는다.
- 두 번째 도시의 기름값과 첫 번째 도시의 기름값을 비교해 더 싼 값을 가진 도시에서 기름을 넣는다.
- 다음 도시로 이동하며 같은 과정을 반복해 마지막 도시에 도착한다.
이어서 코드 구현은 아래와 같은 로직으로 구현했다.
- 도시의 수 n을 입력받아 크기가 각각 [n - 1], [n]인 배열(리스트) distances와 prices를 채워준다.
- 최소 비용, 즉 정답을 저장할 변수 result를 0으로 초기화한다.
- 현재까지의 리터당 최소 가격을 저장할 변수 minPrice를 prices[0], 즉 첫 번째 도시의 기름 가격으로 초기화한다.
- 반복문을 돌며 두 번째 도시부터 마지막 도시를 순회하며 다음과 같은 작업을 수행한다.
- result에 현재까지의 리터당 최소 가격과 이전 도시에서 현재 도시까지의 거리를 곱해 더해준다.
- minPrice보다 현재 도시의 리터당 가격이 작다면 현재 도시의 값으로 갱신한다.
- 결과를 출력한다.
Java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Prob13305 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
long[] distances = new long[n - 1];
long[] prices = new long[n];
StringTokenizer st = new StringTokenizer(br.readLine());
for (int i = 0; i < n - 1; i++) {
distances[i] = Long.parseLong(st.nextToken());
}
st = new StringTokenizer(br.readLine());
for (int i = 0; i < n; i++) {
prices[i] = Long.parseLong(st.nextToken());
}
long result = 0;
long minPrice = prices[0];
for (int i = 1; i < n; i++) {
result += minPrice * distances[i - 1];
if (prices[i] < minPrice) {
minPrice = prices[i];
}
}
System.out.println(result);
}
}
Python
import sys
n = int(sys.stdin.readline().rstrip())
distances = list(map(int, sys.stdin.readline().rstrip().split()))
prices = list(map(int, sys.stdin.readline().rstrip().split()))
result = 0
min_price = prices[0]
for i in range(1, n):
result += min_price * distances[i - 1]
if prices[i] < min_price:
min_price = prices[i]
print(result)
Performance
'Algorithm > [Java+Python+JavaScript]BackJoon' 카테고리의 다른 글
[Java+Python]1780번, 종이의 개수 (0) | 2023.06.07 |
---|---|
[Java+Python]1992번, 쿼드 트리 (1) | 2023.06.06 |
[Java+Python]2630번, 색종이 만들기 (2) | 2023.06.05 |
[Java+Python]1541번, 잃어버린 괄호 (0) | 2023.06.02 |
[Java+Python]11339번, ATM (0) | 2023.05.31 |
[Java+Python]1931번, 회의실 배정 (0) | 2023.05.30 |
- Total
- Today
- Yesterday
- 맛집
- 유럽
- 지지
- Algorithm
- 세모
- 스프링
- 유럽여행
- Python
- 세계여행
- BOJ
- 백준
- 야경
- 중남미
- RX100M5
- java
- spring
- 칼이사
- Backjoon
- a6000
- 기술면접
- 여행
- 세계일주
- 스트림
- 리스트
- 알고리즘
- 자바
- 남미
- 면접 준비
- 동적계획법
- 파이썬
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |