https://www.acmicpc.net/problem/2805
2805번: 나무 자르기
문제 상근이는 나무 M미터가 필요하다. 근처에 나무를 구입할 곳이 모두 망해버렸기 때문에, 정부에 벌목 허가를 요청했다. 정부는 상근이네 집 근처의 나무 한 줄에 대한 벌목 허가를 내주었고, 상근이는 새로 구입한 목재절단기을 이용해서 나무를 구할것이다. 목재절단기는 다음과 같이 동작한다. 먼저, 상근이는 절단기에 높이 H를 지정해야 한다. 높이를 지정하면 톱날이 땅으로부터 H미터 위로 올라간다. 그 다음, 한 줄에 연속해있는 나무를 모두 절단해버린다. 따
www.acmicpc.net
랜선 자르기 문제와 비슷하게 parametric search문제이다.
0부터 절단기의 최대길이가 될 수 있는 값(나무길이 중 가장 큰 값)까지를 이분 탐색을 진행하면서 필요한 나무만 가져갈 수 있는 절단기의 최대길이를 구한다.
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
#include <iostream>
#include <algorithm>
using namespace std;
int n, m;
long long ans;
long long namu[1000000];
void solve(int left, int right) {
long long h = (left + right) / 2;
long long len = 0;
//절단기 높이를 h(mid값)로 했을때 가져갈 수 있는 나무길이(len)을 구한다.
//(각 나무에서 h만큼 자르고 남은 값을 더한다)
for (int i = 0; i < n; i++) {
if (namu[i] >= h) {
len += (namu[i] - h);
}
}
if (len > m) {
if (left >= right) {
//left가 right보다 같거나 커진 경우 이분탐색 중지하고 ans 값과 현재 h를 비교
if (ans < h) ans = h;
return;
}
//len이 가져가려는 길이m보다 크면 절단기 크기를 더 크게 해도 된다.
solve(h + 1, right);
}
else if (len < m) {
//len이 가져가려는 길이 m보다 작으면 절단기 크기h를 더 작게해야 한다.
solve(left, h - 1);
}
else {
//같은 경우에는 현재 절단기 크기와 비슷해서 최댓값을 저장
if (ans < h) ans = h;
return;
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m;
for (int i = 0; i < n; i++) {
cin >> namu[i];
}
//정렬
sort(namu, namu + n);
//left값은 0 right값은 나무 길이의 최대 값
solve(0, namu[n - 1]);
cout << ans << '\n';
return 0;
}
Colored by Color Scripter
|
'BOJ' 카테고리의 다른 글
[BOJ] 11053. 가장 긴 증가하는 부분 수열 (0) | 2020.01.29 |
---|---|
[BOJ] 2167. 2차원 배열의 합 (0) | 2020.01.24 |
[BOJ] 1654. 랜선 자르기 (0) | 2020.01.20 |
[BOJ] 10816. 숫자 카드 2 (0) | 2020.01.20 |
[BOJ] 5567. 결혼식 (0) | 2019.11.13 |