[백준] 3079번 - 입국심사 (Gold 5)
업데이트:
문제 링크
문제 설명
문제는 길게 쓰여져있지만 수식으로 요약하면 간단하다.
$\sum_{i=1}^{N}{a_i} = M$(단, $a_i$는 모두 0 이상의 정수)일 때 $\mathrm{max}\lbrace{a_i T_i : i = 1, \cdots N}\rbrace$의 최솟값을 구하는 문제이다.
정답 코드 및 설명
T초 이내로 심사를 마칠 수 있는 사람의 수는 최대 $\sum_{i=1}^{N}{(T / T_i)}$이다.
$T_i$ 중 가장 작은 값이 t라면, Mt초 이내에는 반드시 심사를 끝낼 수 있다.
위 두 사실을 이용하여 매개변수탐색을 사용한다.
아래 코드에서는 t를 구하기 위해 정렬을 사용했는데, 이는 불필요하고 최솟값만 구하면 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class BOJ3079 {
int n, m;
int[] t;
void input() 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());
t = new int[n];
for (int i = 0; i < n; i++)
t[i] = Integer.parseInt(br.readLine());
Arrays.sort(t);
}
long minTime() {
long start = m * (long) t[0];
long end = 0;
while (start > end + 1) {
long mid = (start + end) / 2;
if (maxPeople(mid) >= m) start = mid;
else end = mid;
}
return start;
}
long maxPeople(long mid) {
long people = 0;
for (int i = 0; i < n; i++)
people += mid / t[i];
return people;
}
void solution() throws IOException {
input();
System.out.println(minTime());
}
public static void main(String[] args) throws IOException {
new BOJ3079().solution();
}
}
댓글남기기