FatMouse 準備了 M 磅貓糧,要與守衛倉庫的貓咪交易 JavaBean。倉庫有 N 個房間,第 i 個房間有 J[i] 磅 JavaBean,需要 F[i] 磅貓糧。可以按比例交易:支付 F[i]×a% 貓糧可獲得 J[i]×a% JavaBean(a 為實數)。求最大可獲得的 JavaBean 總量,精確到小數點後 3 位。
每個房間的「性價比」為 `rate = J[i] / F[i]`(每磅貓糧換得的 JavaBean)。為了最大化總收益,應優先選擇單價最高的房間完全交易,直到貓糧耗盡或房間用完。這是典型的**分數背包問題**,貪心策略最優。
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
struct Room {
int j, f;
bool operator<(const Room& other) const {
return (double)j / f > (double)other.j / other.f; // 降序
}
};
int main() {
int M, N;
while (scanf("%d %d", &M, &N) == 2 && M != -1) {
vector<Room> rooms(N);
for (int i = 0; i < N; ++i) scanf("%d %d", &rooms[i].j, &rooms[i].f);
sort(rooms.begin(), rooms.end());
double maxBean = 0.0;
for (int i = 0; i < N; ++i) {
if (M >= rooms[i].f) {
maxBean += rooms[i].j;
M -= rooms[i].f;
} else {
maxBean += (double)rooms[i].j * M / rooms[i].f;
break;
}
}
printf("%.3f\n", maxBean);
}
return 0;
}
時間:O(N log N) 主要耗在排序。空間:O(N) 存儲房間信息。N ≤ 1000,極易通過。