https://www.acmicpc.net/problem/6236
6236번: 용돈 관리
현우는 용돈을 효율적으로 활용하기 위해 계획을 짜기로 하였다. 현우는 앞으로 N일 동안 자신이 사용할 금액을 계산하였고, 돈을 펑펑 쓰지 않기 위해 정확히 M번만 통장에서 돈을 빼서 쓰기로
www.acmicpc.net
모자라게 되면 남은 금액은 통장에 집어넣고 다시 K원을 인출한다.라는 조건에서 첫 번째 생각은 총 N일동 안 자신이 사용할 금액 중 가장 큰 값 이상이어야 문제조건 자체가 성립된 다는 것이다.
당연한 말인 게 남은 금액을 통장에 집어넣기 때문에 만약 사용할 금액 중 가장 큰 값보다 작다면, K원 인출, K원 집어넣기 무한반복 ,,,,,,,
이렇게 첫 번째 조건은 만족한 것 같고, 두 번째로는 정확히 M번을 인출한다는 것인데 이 조건은 어떻게 생각해야 하나 곰곰이 보다가, 남은 금액이 그날 사용할 금액보다 많더라도 남은 금액은 통장에 집어넣고 다시 K원을 인출이라고 했기 때문에 남은 금액이 그날 사용할 금액보다 많을 경우는 통장에 최대한 안 집어넣는 방식을 적용해야겠다고 생각했다.
MAX값(N일동 안 사용할 금액 중 가장 큰 값) 보다 크면서, M번 인출할 때 사용할 금액보다 많을 경우, 통장에 집어넣지 말자.
그렇다면 이건 대체 뭘 이용해야 할까,,,? Greedy인가,,?
한참 생각하다가 내가 지금 알고 있는 조건은 위에서 말한 최솟값과, 문제 자체에서 주어진 최댓값인 점에서 이분탐색으로 들어가도 좋을 것 같다고 생각이 들었다.
사실 나도 이분탐색이라고 생각이 드는데 너무 많은 시간이 들었고, 조건도 생각보다 까다로웠다.
https://www.acmicpc.net/blog/view/109
이분 탐색(Binary Search) 헷갈리지 않게 구현하기
개요 이분 탐색은 off-by-one error가 발생하기 쉬워서 늘 헷갈립니다. 이분 탐색 문제를 풀다보면 탈출 조건으로 lo <= hi, lo < hi, lo + 1 < hi 중 어느 걸 선택해야 할 지, 정답이 lo인지 hi인지 (lo + hi) / 2
www.acmicpc.net
이분탐색이 헷갈리신 분들은 이글에서 매우 잘 설명해주시니 한번 보는 걸 추천해요,,
내가 이해하기로는 문제의 답이 두 구간으로 나뉘면 답이 달라지는 경계를 찾는 방식으로 접근하면 된다고 이해했다.
또한 정답이 low가될수도 있고, high이 될수도 있는데 이는 문제 조건에 따라 변경해주어야한다.
소스코드
#include <iostream>
#define MAX 100001
using namespace std;
int n, m, price[MAX];
//최소화된 인출금액 K 구하기
int main() {
cin >> n >> m;
int high = 0;
int low = 0;
for (int i = 1; i <= n; i++) {
cin >> price[i];
//각 이용금액중 최대값을 저장
high += price[i];
}
int cnt, remain, res = 0;
while (low <= high) {
//mid값을 최소금액 K라고 정함
int mid = (high + low) / 2;
//쓰고 남아 있는 금액 변수
remain = mid;
cnt = 1;
bool possible = true;
for (int i = 1; i <= n; i++) {
//인출할 금액보다 K가 작으면 불가능
if (price[i] > mid) {
possible = false;
break;
}
else if (price[i] > remain) {
remain = mid;
cnt++;
}
remain -= price[i];
}
// 인출 횟수가 M보다 크다는 말은 금액이 너무 작다는 의미
if (!possible || cnt > m) low = mid + 1;
else {
res = mid;
high = mid - 1;
}
}
cout << res;
}
'Algorithm > Binary Search' 카테고리의 다른 글
[BAEKJOON] 1348번 주차장 (0) | 2024.06.01 |
---|---|
[BAEKJOON] 1806번 부분합 (1) | 2024.04.16 |
[BAEKJOON] 2568번 전깃줄 - 2 (0) | 2024.03.30 |
[BAEKJOON] 19637번 IF문 좀 대신 써줘 (0) | 2024.03.25 |
[BAEKJOON] 2613번 숫자구슬 (1) | 2024.03.16 |