어떤 식으로 푸는지 도저히 생각이 안나서 구글에 검색을 해봤다...
범위가 매우 크고 최솟값을 찾는 문제는
이분탐색과 파라메트릭 서치를 사용해야 한다는 것을 새로 배우게 되었다.
이런 문제들이 코테에 나온다면...
#include <string>
#include <vector>
using namespace std;
long long solution(int a, int b, vector<int> g, vector<int> s, vector<int> w, vector<int> t) {
long long answer = 10e5 * 4 * 10e9;
long long start = 0;
long long end = 10e5 * 4 * 10e9;
while (start <= end) { // 이분 탐색이 끝날 때까지
long long mid = (start + end) / 2;
long long gold_carry = 0;
long long sil_carry = 0;
long long add_carry = 0;
for (int i = 0; i < s.size(); i++) {
long long now_gold = (long long)g[i];
long long now_sil = (long long)s[i];
long long now_w = (long long)w[i];
long long now_t = (long long)t[i];
long long move_cnt = mid / (now_t * 2);
if (mid % (now_t * 2) >= t[i]) move_cnt++; //편도로 1번더 갈 수 있다면 1회 추가
gold_carry += (now_gold < move_cnt* now_w) ? now_gold : move_cnt * now_w;
// 시간 내에 옮길 수 있는 총 금의 양을 구한다.
sil_carry += (now_sil < move_cnt* now_w) ? now_sil : move_cnt * now_w;
// 시간 내에 옮길 수 있는 총 은의 양을 구한다.
add_carry += (now_gold + now_sil < move_cnt* now_w) ? now_gold + now_sil : move_cnt * now_w;
// 시간 내에 옮길 수 있는 총 금속의 양을 구한다.
}
if (gold_carry >= a && sil_carry >= b && add_carry >= a + b) {
// 총 금의 양도 충분하고, 은도 충분하고, 옮길 수 있는 금속의 양도 충분하면 다음 탐색을 한다.
end = mid - 1;
answer = min(mid, answer);
}
else {
start = mid + 1;
}
}
return answer;
}