Computer Science
탄탄한 기반 실력을 위한
전공과 이론 지식 모음
Today I Learned!
배웠으면 기록을 해야지
TIL 사진
Flutter 사진
Flutter로 모바일까지
거꾸로캠퍼스 코딩랩 Flutter 앱개발 강사
스파르타코딩클럽 즉문즉답 튜터
카카오테크캠퍼스 3기 학습코치
프로필 사진
박성민
임베디드 세계에
발을 들인 박치기 공룡
임베디드 사진
EMBEDDED SYSTEM
임베디드 SW와 HW, 이론부터 실전까지
ALGORITHM
알고리즘 해결 전략 기록
🎓
중앙대학교 소프트웨어학부
텔레칩스 차량용 임베디드 스쿨 3기
애플 개발자 아카데미 1기
깃허브 사진
GitHub
프로젝트 모아보기
Instagram
인스타그램 사진

Develop/알고리즘

[백준] 13305 - 주유소

sm_amoled 2021. 12. 26. 13:07

문제링크

https://www.acmicpc.net/problem/13305

문제

어떤 나라에 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 이하의 자연수이다.

출력

표준 출력으로 제일 왼쪽 도시에서 제일 오른쪽 도시로 가는 최소 비용을 출력한다.

조건

  • 시간 제한 : 2s
  • 메모리 제한 : 512MB

해설

쉽게 생각하면, 이번 도시에서 기름을 필요한 만큼 사고, 다음 기름값이 더 저렴한 도시에 가서 기름을 필요한 만큼 사고, 다음 기름값이 더욱 더 저렴한 도시에 가서 기름을 필요한 만큼 사면서 마지막 도시까지 가면 된다. 즉, 첫 도시에서 부터 마지막 도시까지 기름을 구매하는 도시의 기름값이 내림차순으로 정렬되면 된다.

  5 - 2 - 4 - 1
→ 5 - 2 - x - 1

  6 - 7 - 4 - 8 - 3 - 1 - 2
→ 6 - x - 4 - x - 3 - 1 - x

도시의 기름값을 입력받으면서, 이전 도시의 기름값보다 비싸면 이전 도시의 기름값으로 현재 이동하고자 하는 도시 사이의 거리를 주행할 기름을 미리 구매한다. 이전 도시의 기름값보다 저렴하면 이제부터 이 도시의 기름값으로 기름을 구매한다.

풀이

각 도시 사이의 거리값을 입력받아준다.

int N;
cin >> N;

vector<int> city(N);
vector<int> distance(N-1);

for(int i = 0; i < N-1; i++) {
    cin >> distance[i];
}

기름값의 최댓값이 리터당 1,000,000,000 이므로, 거리x리터당 기름값 의 계산식이 오버플로우가 발생하지 않도록 long long 자료형으로 선언해준다. cost는 마지막 도시까지 이동할 때 필요한 총 금액이고, beforePrice는 현재 계산중인 도시 이전까지의 도시들 중 가장 저렴한 기름의 가격을 저장한다.

long long cost = 0;
long long beforePrice;

A 도시까지 갈 때, A 도시의 기름값은 필요없으므로, 먼저 A 도시까지 갈 때 필요한 기름값 cost를 계산해준다. 그 다음, A 도시의 기름값을 입력받고, 이 값이 원래 기름을 구매하던 이전 도시의 기름값과 비교한다. 만약 A 도시의 기름값이 저렴하다면 이후로 주행할 때 필요한 기름값은 A 도시에서 구매하고, 비싸다면 이전에 기름을 사던 도시에서 필요한 만큼 기름을 계속 구매한다. 가장 첫번째 도시는 cost를 계산할 필요가 없으므로, 반복문을 수행하기 이전에 미리 도시의 기름값을 입력받아 beforePrice에 넣어둔다.

cin >> beforePrice;
for(int i = 1; i < N; i++) {
    cost += beforePrice * distance[i-1];
    
    int input;
    cin >> input;
    if(beforePrice > input) beforePrice = input;
}

cout << cost;

코멘트

그냥 도시의 기름값들을 내림차순으로 만들 수 있는 원소들만 뽑아서 계산하면 쉽게 해결되는 문제였다!


코드

#include <iostream>
#include <vector>

using namespace std;

int main() {
    int N;
    cin >> N;
    
    vector<int> city(N);
    vector<int> distance(N-1);
    
    for(int i = 0; i < N-1; i++) {
        cin >> distance[i];
    }
    
    long long cost = 0;
    long long beforePrice;
    
    cin >> beforePrice;
    for(int i = 1; i < N; i++) {
        cost += beforePrice * distance[i-1];
        
        int input;
        cin >> input;
        if(beforePrice > input) beforePrice = input;
    }
    
    cout << cost;
    
      
    return 0;
}

320x100

'Develop > 알고리즘' 카테고리의 다른 글

[백준] 5086 - 배수와 약수  (0) 2021.12.26
[백준] 7579 - 앱  (0) 2021.12.26
[백준] 11047 - 동전 0  (0) 2021.12.26
[백준] 2294 - 동전 2  (0) 2021.12.26
[백준] 2609 - 최대공약수와 최소공배수  (0) 2021.12.26