반응형

문제 출처 :


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



알고리즘 분석 :


문제 해결에 필요한 사항

1. 이진 탐색 응용


이 문제는 DP라고 생각이 처음 들 수 있겠지만, 자세히 확인해보면 이진 탐색으로 빠르게 해결 할 수 있다.


하지만 이진 탐색 코드를 그대로 쓰면 안되고, 조금 응용해서 써야한다.


소스코드에 대한 설명은 주석을 통해 자세히 달아두었다.


소스 코드 : 


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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <iostream>
#include <cstring>
#include <algorithm>
 
using namespace std;
 
int tree[1000001];
 
int binarysearch(int n, int target)
{
    int first = 0;
    int last = tree[0];
    int mid = 0;
 
    long long int ans = 0;
 
    while (first <= last)
    {
        // first :: 가장 낮은 나무의 높이, 처음은 0으로 잡는다.
        // last :: 가장 높은 나무의 높이, 정렬한 상태이니 tree[0]가 가장 높다.
        // mid의 의미 :: 가장 높은 나무와 낮은 나무의 / 2한 값
        // 이것을 이용하여 잘랐을 때의 길이의 합을 가져올 수 있다.
 
 
        mid = (first + last) / 2;
 
        // 전체 나무의 길이를 더한다.
        for (int i = 0; i < n; i++)
            ans += tree[i];
 
        // mid보다 아래 나무 즉, 잘리지 않은 나무의 길이는 빼줌으로써
        // ans변수에 벌목했을때의 나무 길이를 가져올 수 있다.
        for (int i = 0; i < n; i++)
        {
            if (tree[i] >= mid)
                ans -= mid;
            else
                ans -= tree[i];
        }
 
        if (target == ans) // 정답이 타겟과 같다면
            return mid; // 탐색 완료
 
        else // 타겟이 아니라면 탐색 대상을 반으로 줄인다.
        {
            if (target < ans)
                first = mid + 1;
 
            else
                last = mid - 1;
        }
 
        ans = 0;
 
    }
 
    // 만약 이진 탐색에서 탐색을 실패할 시,
    // mid를 마지막으로 구해주고 리턴해준다.
    mid = (first + last) / 2;
    return mid;
}
 
bool comp(const int &a, const int &b)
{
    return a > b;
}
 
int main()
{
    int n, want;
 
    scanf("%d %d"&n, &want);
 
    for (int i = 0; i < n; i++)
        scanf("%d"&tree[i]);
 
    // 나무를 내림차순으로 정렬해준다.(가장 큰 나무를 잡아내기 위해)
    sort(tree, tree + n, comp);
 
    // 나무 개수, 원하는 벌목 길이
    cout << binarysearch(n, want);
 
 
    return 0;
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus


반응형

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

[2003번] 수들의 합 2  (2) 2016.11.18
[13415번] 정렬 게임  (0) 2016.11.10
[1260번] DFS와 BFS  (0) 2016.11.09
[2167번] 2차원 배열의 합  (0) 2016.11.08
[1652번] 누울 자리를 찾아라  (0) 2016.11.08