- 이 문제는 2회차푸는 문제다.
- x길이의 고정된길이로 막대를 자른다는 제약조건이 있다. (파악하기 힘들었음)
* 매개변수 탐색 학습, 의사코드
- 매개변수 탐색은 이분탐색의 응용편이다.
- f(x)를 정의하라. // f(x) : 랜선의 길이가 x일때, 갯수가 11개 이상이 나오는지.
- 우선, f(1)과 f(끝)을 직접 구한다.
- 랜선의 길이가 1일때, 갯수는 무조건 11개 이상이나온다.
- 랜선의 길이가 max일때, 갯수는 무조건 1개이다.
- f(mid)가 참인경우
- 같은숫자를 연결하면된다.
- 즉, f(1) ~ f(mid)는 계산할필요없이 모두 1인것이다.
- 이경우, 우측으로 재귀적으로 재탐색하면 된다.
- 이때, mid자체도 정답의 범위에( true이므로) 포함되기떄문에, st = mid로 둬야함에 주의
- f(mid)가 거짓인경우
- 같은숫자를 연결하면된다.
- 즉, f(mid)~f(max)는 계산할필요없이 모두 1인것이다.
- 이경우, 좌측으로 재귀적으로 재탐색하면 된다.
- 마지막으로 값이 1개가 남을때까지 진행하면, 그게 정답이다.
* go 함수 구현
- 길이가 x 일때, 막대기갯수가 11(k)개 이상 나오는지 리턴한다.
ll go(ll x) {
ll cnt = 0; //막대기갯수
for (int i = 0; i < n; ++i) {
cnt += arr[i] / x;
}
return cnt >= k;
}
* 전체코드
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int ret;
int n, k;
int arr[10004];
ll go(ll x) {
ll cnt = 0; //막대기갯수
for (int i = 0; i < n; ++i) {
cnt += arr[i] / x;
}
return cnt >= k;
}
int main()
{
cin >> n >> k;
for (int i = 0; i < n; ++i) {
cin >> arr[i];
}
ll st = 0;
ll en = pow(2,31) - 1;
while (st < en) {
ll mid = (st + en +1 ) / 2;
if (go(mid)) {
st = mid;
}
else {
en = mid - 1;
}
}
cout << st;
return 0;
}
* 레퍼런스
https://www.youtube.com/watch?v=F6lKjRDlOpk
'Algorithm > 매개변수 탐색' 카테고리의 다른 글
[Algo] 공유기설치 c++ // 매개변수 탐색 hard (0) | 2024.09.12 |
---|---|
[Algo] 백준 예산 c++ // 매개변수 탐색 (0) | 2024.09.09 |
백준 2110 공유기설치 c++ // 매개변수탐색, 이분탐색 hard (0) | 2024.03.29 |
백준 2805 나무자르기 c++ // 이분탐색, 매개변수탐색, 정답후보를 for문 돌려라 (0) | 2024.03.10 |