算法竞赛进阶指南0x07 贪心
P2240 【深基12.例1】部分背包问题
因为我们可以随意分割金币,所以我们以每堆金币的平均价值为关键字排序,尽可能多地选单位价值最大的金币。
参考代码:
#include <bits/stdc++.h>
#define i64 long long
#define lowbit(x) (x & (-x))
typedef unsigned long long ll;
const int MOD = 1e9 + 7;
template <typename _T>
inline void read(_T &f) {
f = 0; _T fu = 1; char c = getchar();
while (c < '0' || c > '9') { if (c == '-') { fu = -1; } c = getchar(); }
while (c >= '0' && c <= '9') { f = (f << 3) + (f << 1) + (c & 15); c = getchar(); }
f *= fu;
}
struct node {
int m, v;
double value;
};
bool cmp(node x, node y) {
return x.value > y.value;
}
int main() {
int n, t;
read(n), read(t);
// t : 容量
std::vector<node> nums(n + 1);
for (int i = 1; i <= n; i++) {
read(nums[i].m), read(nums[i].v);
nums[i].value = nums[i].v * 1.0 / nums[i].m;
}
std::sort(nums.begin() + 1, nums.end(), cmp);
double ans = 0;
for (int i = 1; i <= n; i++) {
if (t >= nums[i].m) {
t -= nums[i].m;
ans += nums[i].v;
} else {
ans += nums[i].value * t;
break;
}
}
std::cout << std::fixed << std::setprecision(2) << ans << "\n";
return 0;
}