백준 1477번 - 휴게소 세우기

2025. 5. 20. 17:33·코딩테스트

구현 방법

이 문제는 여러 가지의 풀이를 생각해 볼 수 있다.

  1. 절차적인 방법
    dfs 을 사용하여 구현하는 방법이 있을 것이다.
    각 구간의 길이를 구하고 각 구간에 몇 개의 휴게소가 추가될 수 있을 지를 결정하는 방식으로 구현될 수 있다.
    이렇게 구현했을 때 시간 복잡도는 C(N + M, M) * (N + 1) 이 되어 지수적으로 시간 복잡도가 상승한다.
  2. dp
    dp를 사용하는 방식에서 중요한 것은 배열, 점화식, 초기값이다. 
    배열을 결정할 때 독립변수를 결정해야 하는데 이 문제에서는 구간 인덱스와 휴게소 개수일 것이다.
    시간 복잡도는 O(N * M * M) 이고 실제 문제에서 입력값이 제한되어 있기 때문에 시간 안에 해결할 수 있다.
  3. 그리디 변형
    가장 큰 구간에 휴게소를 추가하는 방식으로 풀이가 가능하다. 이 때, 휴게소를 해당 구간에 넣었을 때 구간의 길이는 (휴게소 개수 + 1) 로 나눠진 값이다. 그래서 총 M 개의 휴게소를 추가하면 된다. 
    이 때, 가장 큰 구간을 꺼내기 위해서 우선순위 큐를 활용한다.
    시간 복잡도는 우선순위 큐 삽입 (logN) * 휴게소 수(M) 이다. 

코드

1. 절차적인 방법(dfs)

void dfs(int idx, int num){
	// 마지막 idx 인 경우
    if() ~
    
    for(int i = 0; i <= num; i++){
    	arr[idx] = i;
    	dfs(idx + 1, num - i);
    }
}

 

2. dp

for(int i = 0; i <= N; i++){
	for(int j = 0; j <= M; j++){
    	for(int k = 0; k <= j; k++){
        	int mxSeg = (distance[i] + k) / (k + 1);
            int candidate = Math.max(dp[i - 1][j - k], mxSeg);
            dp[i][j] = Math.min(dp[i][j], candidate);
        }
    }
}

 

3. 그리디

package greedy;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class BJ1477 {
    private static int N, M, L;
    private static int[] locations;
    private static int[] distances;
    public static void main(String[] args) throws IOException {
        readInput();
        solve();
    }

    private static void readInput() throws IOException{
        BufferedReader br = new BufferedReader((new InputStreamReader(System.in)));
        StringTokenizer st = new StringTokenizer(br.readLine());

        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        L = Integer.parseInt(st.nextToken());

        locations = new int[N + 2];
        distances = new int[N + 1];
        
        st = new StringTokenizer(br.readLine());
        for(int i = 1; i <= N; i++){
            locations[i] = Integer.parseInt(st.nextToken());
        }
        locations[N + 1] = L;
    }

    private static void solve(){
        Arrays.sort(locations);
        
        PriorityQueue<Section> pq = new PriorityQueue<>((a, b) -> {
            return b.distance - a.distance;
        });

        // 초기화
        for(int i = 0; i <= N; i++){
            distances[i] = locations[i + 1] - locations[i];
            pq.add(new Section(i, 1, distances[i]));
        }

        for(int i = 0; i < M; i++){
            Section s = pq.poll();
            int distance = distances[s.idx]/(s.num + 1) + (distances[s.idx] % (s.num + 1) == 0 ? 0 : 1);
            pq.add(new Section(s.idx, s.num + 1, distance));
        }

        System.out.println(pq.poll().distance);
    }

    private static class Section{
        private int idx;
        private int num;
        private int distance;

        public Section(int idx, int num, int distance){
            this.idx = idx;
            this.num = num;
            this.distance = distance;
        }
    }
}

결과

'코딩테스트' 카테고리의 다른 글

백준 1931번 - 회의실 배정  (0) 2025.05.19
백준 15685번 - 치킨 배달  (0) 2025.05.18
백준 12100번 - 2048(easy)  (0) 2025.05.16
백준 18808번 - 스티커 붙이기  (0) 2025.05.16
백준 15683번 - 감시  (0) 2025.05.15
'코딩테스트' 카테고리의 다른 글
  • 백준 1931번 - 회의실 배정
  • 백준 15685번 - 치킨 배달
  • 백준 12100번 - 2048(easy)
  • 백준 18808번 - 스티커 붙이기
khw7385
khw7385
khw7385 님의 블로그 입니다.
  • khw7385
    khw7385 님의 블로그
    khw7385
  • 전체
    오늘
    어제
    • 분류 전체보기 (43)
      • 코딩테스트 (7)
      • 자바 (3)
      • 스프링 (3)
      • cs (7)
        • 자료구조 (3)
        • 알고리즘 (1)
        • 객체지향 (3)
      • 개발일지 (6)
        • 트러블슈팅 (1)
      • 데이터베이스 (3)
        • Redis (2)
        • MySQL (1)
      • 기타 (2)
      • devops (6)
      • LG CNS AM INSPIRE (6)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
khw7385
백준 1477번 - 휴게소 세우기
상단으로

티스토리툴바