용꿀
꼬마개발자허니
용꿀
전체 방문자
오늘
어제
  • 분류 전체보기 (248)
    • 개발 (75)
      • 스프링 입문 (7)
      • 스프링 기본 (9)
      • ToDo List using JPA (2)
      • 스프링 개념 (9)
      • 스프링 부트와 AWS로 혼자 구현하는 웹 서비스 (8)
      • 스프링 MVC (3)
      • CS (19)
      • 개발 팁 (8)
      • 스프링 MSA (5)
      • 곰터뷰🐻 (5)
    • 알고리즘 (169)
      • 알고리즘 문제 풀이 (165)
    • 잡동사니 (1)
      • 노래 가사 (1)
hELLO · Designed By 정상우.
용꿀

꼬마개발자허니

(JAVA) 금과 은 운반하기
알고리즘/알고리즘 문제 풀이

(JAVA) 금과 은 운반하기

2024. 1. 21. 23:57

문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/86053

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

풀이

이분 탐색과 Parametric Search를 사용한 풀이이다.

Parametric Search는 특정 상황을 만족하는 특정값의 최대 혹은 최댓값을 구하는 최적화 문제에 적용할 수 있음을 생각하고, 이 알고리즘을 이번 문제에 적용할 생각을 하는 것이 중요하다.

 

Parametric Search는 최적화 문제를 결정 문제로 바꾸는 것이다. 이번에 풀이한 '금과 은 운반하기' 문제를 예시로 들면 원래는 "새로운 도시 건설을 위한 모든 금과 은을 전달하는 최소 시간을 구하시오" 라는 최적화 문제였지만, 이를 "현재 가정한 시간 내에 모든 금과 은을 전달할 수 있는가?"라는 결정 문제로 해결해야한다는 것이다.

 

이론상 최대 시간과 이론상 최소 시간의 중간값부터 시작하여, 이분 탐색을 통해 최종적으로 모든 금과 은을 시간 내에 전달할 수 있는 최소 시간을 찾으면 된다.

class Solution {
    public long solution(int a, int b, int[] g, int[] s, int[] w, int[] t) {
        long answer = (long) (2 * 10e9 * 2 * 10e5); // 이론상 최대 시간으로 가정
        long min = 0; // 이론상 최소 시간
        long max = (long) (2 * 10e9 * 2 * 10e5); // 이론상 최대 시간
        
         while (min <= max) { // 이분 탐색 시작
            long mid = (min + max) / 2; // 중간값
            long gold = 0;
            long silver = 0;
            long add = 0;
             
            // 전체 도시를 순회하며, 시간 내에 옮길 수 있는 금과 은의 양과 총 양(add)를 더해주기
            for(int i = 0; i < g.length; i++) {
                int curGold = g[i];
                int curSilver = s[i];
                int curWeight = w[i];
                int curTime = t[i];

                long iter = Math.round(mid / curTime / 2.0);
                
                gold += Math.min(curGold, iter * curWeight);
                silver += Math.min(curSilver, iter * curWeight);
                add += Math.min(curGold + curSilver, iter * curWeight);
            }
            // mid 시간 내에 모든 금과 은을 전달할 수 있을 경우
             if (a <= gold && b <= silver && a+b <= add){
                 max = mid - 1;
                 answer = Math.min(mid, answer);
                 continue;
             }
             // 그렇지 못한 경우
             min = mid + 1;
         }
        return answer; // 탐색이 끝났으면 결과 반환
    }
}

 

'알고리즘 > 알고리즘 문제 풀이' 카테고리의 다른 글

(JAVA) 합승 택시 요금  (0) 2024.02.01
(JAVA) 길 찾기 게임  (0) 2024.01.24
(JAVA) 백준 2805번 - 나무 자르기  (1) 2023.12.27
(C++) 백준 9372번 - 상근이의 여행  (0) 2023.06.20
(C++) 백준 1368번 - 물대기  (0) 2023.06.19
    '알고리즘/알고리즘 문제 풀이' 카테고리의 다른 글
    • (JAVA) 합승 택시 요금
    • (JAVA) 길 찾기 게임
    • (JAVA) 백준 2805번 - 나무 자르기
    • (C++) 백준 9372번 - 상근이의 여행
    용꿀
    용꿀

    티스토리툴바