본문 바로가기
Problem Solving/백준

백준 13397 : 구간 나누기 2

by Libi 2021. 9. 6.
반응형

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

 

13397번: 구간 나누기 2

첫째 줄에 배열의 크기 N과 M이 주어진다. (1 ≤ N ≤ 5,000, 1 ≤ M ≤ N) 둘째 줄에 배열에 들어있는 수가 순서대로 주어진다. 배열에 들어있는 수는 1보다 크거나 같고, 10,000보다 작거나 같은 자연수

www.acmicpc.net

[ 문제풀이 ]

최적해를 구하는 문제이기 때문에 결정 문제로 변경하여 파라메트릭 서치를 활용하면 해결할 수 있는 문제이다.

key 값을 기준으로 구간을 나눴을 때 M보다 작다면 정답이 가능하기 때문에 더 작은 key값을 탐색해주고, M보다 크다면 정답이 불가능하기 때문에 더 큰 key값으로 탐색해준다.

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;

public class Main {
	
	static int N, M;
	static int[] data;
	
	public static void main(String[] args) {
		try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
				BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out))) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			N = Integer.parseInt(st.nextToken());
			M = Integer.parseInt(st.nextToken());
			data = new int[N + 1];
			st = new StringTokenizer(br.readLine());
			for (int i = 1; i <= N; ++i) {
				data[i] = Integer.parseInt(st.nextToken());
			}
			
			int l = 0, r = 10001;
			while (l <= r) {
				int m = (l + r) >> 1;
				if (isValid(m)) r = m - 1;
				else l = m + 1;
			}
			bw.write(l + "\n");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static boolean isValid(int key) {
		int count = 1, min = 10001, max = -1;
		for (int i = 1; i <= N; ++i) {
			min = Math.min(min, data[i]);
			max = Math.max(max, data[i]);
			if (max - min > key) {
				count++;
				min = 10001;
				max = -1;
				i--;
			}
		}
		return count <= M;
	}
}

 

 

반응형

'Problem Solving > 백준' 카테고리의 다른 글

백준 12738 : 가장 긴 증가하는 부분 수열 3  (0) 2021.09.12
백준 11085 : 군사 이동  (0) 2021.09.08
백준 9470 : Strahler 순서  (0) 2021.09.04
백준 1029 : 그림 교환  (0) 2021.08.31
백준 2234 : 성곽  (0) 2021.08.30

댓글