따라서 예를들어 [1 2 3 4 5] 가 있을 때, 답이 5일 경우에는 while문을 전부 돌고 나오는 값이 6을 가리켜야 -1 해서 5가 나올 수 있다.
min값은 답이 될 수 있는 가장 작은 값이 오면 됨
0,1 등 문제를 잘 읽고 답이 될 수 있는 가장 작은 값을 넣어주면 됨.
그런데 0이 들어갈경우 divisionByZero 런타임 에러가 날 수 있기 때문에 s는 보통 1 이상으로 책정
0일 경우가 필요하다면 따로 예외처리를 해두는것을 추천
if문에서 비교한 값이 구하는 값의 조건에 부합할 때
→ mid값을 범위에 포함시키지 않는다
if문에서 비교한 값이 구하는 값의 조건에 부합하지 않을떄
→mid값을 범위에 포함시킨다
💡 이유는 upperbound는 결국 조건에 부합하는 값들 중 최댓값보다 하나 더 큰값을 구하는 것임. 따라서 조건에 부합할 경우 최종적으로 s~e구간 사이에 존재하면 안되므로 s=mid+1 을통해 mid를 범위에서 제외시켜야한다
예시 코드
1. 랜선 자르기
using namespace std;
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int k,n,val;
cin>>k>>n;
vector<int> v;
for (int i = 0; i < k; ++i) {
cin>>val;
v.push_back(val);
}
sort(v.begin(),v.end());
int index=k-1;
long long int cnt=0;
long long int s=1,e=v[index];
e++;//max값 1 늘려주기
long long int len=(s+e)/2;
while(s<e){
cnt=0;
for (int i = 0; i < k; ++i) {
cnt+=v[i]/len;
}
if(cnt>=n){//자른 랜선의 개수가 필요한 랜선의 개수보다 같거나 많음=len(mid)값이 조건에 부합함
s=len+1; //len 값을 범위에서 제외함
len=(s+e)/2;
}
else {//자른 랜선의 개수가 필요한 랜선의 개수보다 적음=len(mid)값이 조건에 부합하지 않음
e=len; //len 값을 범위에 포함
len=(s+e)/2;
}
}
cout<<s-1;
}
2. 예산
using namespace std;
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int m,n,val;
cin>>n;
vector<int> v;
for (int i = 0; i < n; ++i) {
cin>>val;
v.push_back(val);
}
cin>>m;
sort(v.begin(), v.end());
long long int len=v[0];
long long int sum=0;
long long int s=1, e=v[n-1];
e++; //max값 1 늘려주기
while(s<e){
sum=0;
for (int i = 0; i < n; ++i) {
if(v[i]>len){
sum+=len;
}
else{
sum+=v[i];
}
}
if(sum<=m){//책정한 예산이 조건에 부합함
s=len+1; //len(mid)값을 범위에서 제외
len=(s+e)/2;
}
else{//책정한 예산이 조건에 부합하지 않음
e=len; //범위에 포함
len=(s+e)/2;
}
}
cout<<s-1;
}
[참고자료]이분탐색을 활용한 UpperBound& LowerBound
1. UpperBound(랜선자르기, 예산)
EX) 관련 문제 예시
2512번: 예산
첫째 줄에는 지방의 수를 의미하는 정수 N이 주어진다. N은 3 이상 10,000 이하이다. 다음 줄에는 각 지방의 예산요청을 표현하는 N개의 정수가 빈칸을 사이에 두고 주어진다. 이 값들은 모두 1 이상
www.acmicpc.net
1654번: 랜선 자르기
첫째 줄에는 오영식이 이미 가지고 있는 랜선의 개수 K, 그리고 필요한 랜선의 개수 N이 입력된다. K는 1이상 10,000이하의 정수이고, N은 1이상 1,000,000이하의 정수이다. 그리고 항상 K ≦ N 이다. 그
www.acmicpc.net
이럴 경우 upper bound를 구한뒤 -1을 한 값이 최댓값을 구하는 방법임을 기억!
upper bound 기억해야 할 것
예시 코드
1. 랜선 자르기
2. 예산
2. LowerBound(게임)
EX) 관련 문제 예시
1072번: 게임
김형택은 지금 몰래 Spider Solitaire(스파이더 카드놀이)를 하고 있다. 형택이는 이 게임을 이길 때도 있었지만, 질 때도 있었다. 누군가의 시선이 느껴진 형택이는 게임을 중단하고 코딩을 하기 시
www.acmicpc.net
이럴 경우 lower bound를 구하는 것이 최솟값을 구하는 방법임을 기억!
lower bound 기억해야 할 것
예시 코드
1. 게임
'풀이기록' 카테고리의 다른 글