문제링크 : https://www.acmicpc.net/problem/2805
문제 접근
- 모든 높이를 기준으로, 전체 나무 순회 >> O(M*N) >> 2e9 * 1e6 >> 시간초과
- 자르려는 높이 증가할수록 얻을수 있는 나무의 길이가 감소 >> 선형적이므로 이진탐색 사용 가능
- 자르려는 높이를 이진탐색 O(lgM)
- 이때 나무 순회하면서 얻을 수 있는 나무를 구함 >> O(N)
- O(N*lgM)
- Lower vs Upper
- 이진 탐색 하는것을 그래프로 그려봤을때
- X축 : 자르려는 높이, Y축 : 얻게되는 나무의 수
- 같은값이 없을때 더 낮은 높이를 설정해야함 > UpperBound
- 더 높은 높이를 설정할 경우, 얻게 되는 나무의 수가 부족한 현상 발생
시간복잡도 계산
- 자르려는 높이를 이진탐색 O(lgM)
- 이때 나무 순회하면서 얻을 수 있는 나무를 구함 >> O(N)
- O(N*lgM)
인트 계산
- 이진탐색 시 필요한 나무길이 : 나무길이 최대 1e6 * 2e9 >> 2e15 >> 인트 사용 불가, long long
- 나무 높이 : 1e9 이하 >> 인트 사용 가능
코드
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 | #include <iostream> using namespace std; typedef long long ll; int tree[1000010]; int N,M; ll chk(int mid) { ll rs=0; for(int i=0; i<N; i++) { rs += max(tree[i]-mid, 0); } return rs; } int binsearch(int M, int st, int en) { if(st==en) return st; int mid = (st+en+1)/2; if(chk(mid) >= M) return binsearch(M, mid, en); else return binsearch(M, st, mid-1); } int main() { cin >> N >> M; for(int i=0; i<N; i++) cin >> tree[i]; cout << binsearch(M,0,1e9) << '\n'; return 0; } | cs |
문제유형
- 이진탐색 - 케이스
- 이진 탐색 문제 중 정답이 되는 값을 이진탐색 하는 문제
- 이와 반대 유형으로 '이진탐색 - 모든 케이스'
- 모든 케이스에 대해서, 연산을 이진탐색 해주는 유형
- 모든 케이스에 대해서, 연산을 이진탐색 해주는 유형
비슷한 문제
'알고리즘 > 백준' 카테고리의 다른 글
백준 5052 전화번호 목록 쉬운 풀이(C++/CPP) (0) | 2021.02.07 |
---|---|
백준 2252 줄 세우기 쉬운 풀이(C++/CPP) (0) | 2021.02.07 |
백준 14226 이모티콘 (0) | 2021.02.06 |
백준 1744 수 묶기 쉬운 풀이(C++/CPP) (0) | 2021.02.06 |
백준 1963 소수 경로 (0) | 2021.02.06 |