전 코테 문제를 푸는것을 좋아하지 않습니다. 하지만 어쩌겠어요.. 해야합니다. 오늘 문제입니다!!
문제 풀이 센스라고 적었는데 왜그런지는 문제 풀이를 진행하면서 기록하도록 하겠습니다!
어떤 나라에 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 | 원래의 제약조건 이외에 아무 제약조건이 없다. |
예제 입력 1 복사
4
2 3 1
5 2 4 1
예제 출력 1 복사
18
예제 입력 2 복사
4
3 3 4
1 1 1 1
오늘 문제는 비교적 긴 설명을 포함하고 있지만, 핵심은 간단합니다. N개의 도시가 일직선 상에 위치하고 있으며, 제일 왼쪽 도시에서 제일 오른쪽 도시로 자동차를 이용해 이동해야 합니다.
자동차는 처음에 기름이 없기 때문에 주유소에서 기름을 충전해야 출발할 수 있습니다. 도로를 1km 이동할 때마다 1리터의 기름이 필요하며, 각 도시에 있는 주유소의 기름 가격은 다릅니다. 이 문제는 각 도시의 주유소에서 기름을 충전하며 제일 오른쪽 도시로 이동할 때, 최소 비용으로 목적지에 도달하는 방법을 계산하는 문제입니다.
문제의 주요 조건:
문제의 핵심:
최소 비용으로 목적지까지 도달하려면, 가능한 한 가장 저렴한 가격의 주유소에서 최대한 많은 기름을 충전해 이동해야 합니다. 따라서, 현재 위치에서 앞으로 이동할 때 현재 주유소의 가격과 다음 도시들의 주유소 가격을 비교해 충전 전략을 세우는 것이 중요합니다.
이러한 접근 방식은 가장 효율적인 선택을 반복하는 그리디 알고리즘의 대표적인 예입니다.
💡 이렇게 문제를 이해하는 과정에서도 문제 분석 및 코드 설계까지 가능할 수 있습니다. 저도 빨리 센스 및 눈치, 실력이 키워졌으면 좋겠습니다!!오랜만에 바로 문제의 해결이 보입니다. 이제 입출력과 제약 조건을 살펴보겠습니다.
min_price
로 초기화합니다.이는 가장 저렴한 가격을 기준으로 계산을 시작하기 위해 필요합니다.result
를 0으로 초기화합니다.min_price
보다 작으면, 더 저렴한 기름값을 발견한 것이므로 min_price
를 갱신합니다.min_price
를 사용해 현재 도시에서 다음 도시까지 이동하는 비용을 계산하고, result
에 누적합니다.result
를 반환합니다.import sys
# 입력 처리
N = int(sys.stdin.readline().strip()) # 도시의 수
distance = list(map(int, sys.stdin.readline().split())) # 도로 길이
price = list(map(int, sys.stdin.readline().split())) # 각 도시의 주유소 가격
def sol(N, distance, price):
# 초기화
min_price = price[0] # 첫 번째 도시의 기름값을 기준으로 초기화
result = 0 # 누적 비용 계산용 변수
# N-1번 순회 (마지막 도시는 이동하지 않음)
for i in range(N-1):
# 더 저렴한 기름값 발견 시 갱신
if min_price > price[i]:
min_price = price[i]
# 현재 구간의 최소 비용 계산
result += min_price * distance[i]
# 누적된 최소 비용 반환
return result
# 결과 출력
print(sol(N=N, distance=distance, price=price))
코드 설명:
N
입니다.distance
리스트로, 각 도로의 길이를 나타냅니다.price
리스트로, 각 도시의 주유소 기름값을 나타냅니다.min_price
를 첫 번째 도시의 기름값으로 초기화합니다.N-1
번 순회하며 다음을 수행합니다:min_price
보다 작으면 갱신합니다.min_price
를 기준으로 다음 도로 구간의 이동 비용을 계산해 result
에 누적합니다.result
를 출력합니다.시간 복잡도:
결과:
이번 문제는 문제 풀이 센스가 중요한 문제였습니다. 문제를 읽으면서 바로 최적화 방법이 떠오르지 않았다면, 여러 시뮬레이션을 통해 규칙을 찾아야 했을 것입니다. 하지만 도로를 순회하며 최소 기름값만 고려하면 된다는 직관이 그리디 알고리즘의 핵심 포인트를 잡게 해줬습니다.
앞으로도 그리디 문제를 풀 때는 매 순간 최적의 선택을 통해 전체 최적화를 달성할 수 있는지 고민하는 연습을 해야겠습니다.
전체 코드는 다음 링크에서 확인할 수 있습니다.
읽어주셔서 감사합니다!!