https://www.acmicpc.net/problem/15759
어려움
<문제설명>
최대 250마리의 소 n마리와 최대 1000의 무게제한W가 주어진다.
각각의 소는 최대 1e6의 무게w와 최대 1e3의 능력t가 주어진다.
소들을 적절히 골라서 무게합이 W이상인 집합 중, 능력합/무게합의 최대값을 x라고 할 때, 1000x의 소수점을 버린 값을 구하라.
<풀이>
고른 소들의 집합을 S라고하면 무게합은 W이상이고 다음을 만족해야 한다.
구해야 할 값은 1000x이므로 이를 y로 치환해서 다시 정리해 보면 다음과 같다.
y값 1~250*1000*1000범위에 대해 이분탐색하면 된다.
int pos(y) : 능력합/무게합이 y가 가능한지?
dp[k] : 무게 합이 k일 때 1000T - yW의 최대값
dp[W] : 무게합이 W이상일 떄 1000T - yW의 최대값
dp[W]>=0이면 가능하고, 그외엔 불가능하다.
<코드>
const int MAX = 1001;
const ll INF = 1e9;
ll n, W, dp[MAX];
P a[255];
bool pos(ll k) {
fill(dp, dp + MAX, -INF);
dp[0] = 0;
for (ll i = 0, w, t; i < n; i++) {
tie(w, t) = a[i];
ll temp = 1000 * t - k * w;
for (ll j = W; j >= 0; j--) {
if (dp[j] == -INF) continue;
dp[min(W, j + w)] = max(dp[min(W, j + w)], dp[j] + temp);
}
}
return dp[W]>=0;
}
int main() {
FAST; cin >> n >> W;
for (int i = 0; i < n; i++) cin >> a[i].first >> a[i].second;
ll lo = 1, hi = 250*1000*1000+1;
while (lo < hi) {
int mid = (lo + hi+1) / 2;
if (pos(mid)) lo = mid;
else hi = mid - 1;
}
cout << lo << '\n';
}
'알고리즘 > 백준 & swacademy' 카테고리의 다른 글
BOJ 11813 - GALAKSIJA (disjoint set, tree, 오프라인쿼리) (0) | 2020.03.18 |
---|---|
BOJ 11510 - TOPOVI (constructive, greedy) (0) | 2020.03.11 |
BOJ 15758 - Milking order (이분탐색, 위상정렬) (0) | 2020.03.01 |
BOJ 15745 - Snow boots (오프라인 쿼리, 유니온 파인드) (0) | 2020.03.01 |
BOJ 14463 - 소가 길을 건너간 이유 9 (세그트리, 라인스위핑) (0) | 2020.02.29 |