算法笔记练习 4.4 贪心 问题 E: FatMouse's Trade
题目
题目描述
FatMouse prepared M pounds of cat food, ready to trade with the cats guarding the warehouse containing his favorite food, JavaBean.
The warehouse has N rooms. The i-th room contains J[i] pounds of JavaBeans and requires F[i] pounds of cat food. FatMouse does not have to trade for all the JavaBeans in the room, instead, he may get J[i]* a% pounds of JavaBeans if he pays F[i]* a% pounds of cat food. Here a is a real number. Now he is assigning this homework to you: tell him the maximum amount of JavaBeans he can obtain.
输入
The input consists of multiple test cases. Each test case begins with a line containing two non-negative integers M and N. Then N lines follow, each contains two non-negative integers J[i] and F[i] respectively. The last test case is followed by two -1’s. All integers are not greater than 1000.
输出
For each test case, print in a single line a real number accurate up to 3 decimal places, which is the maximum amount of JavaBeans that FatMouse can obtain.
样例输入
4 2
4 7
1 3
5 5
4 8
3 8
1 2
2 5
2 4
-1 -1
样例输出
2.286
2.500
思路
类似这个题:PAT B1020 月饼
要用有限的钱(cat food)去换到尽量多的东西(javabeans),那么要尽可能地买便宜的东西,也就是单价低的东西。
所以将所有货仓按照单价从低到高排序,从前往后尽可能地买。
代码
#include <stdio.h>
#include <stdlib.h>
typedef struct{
double java; // 有多少货
double food; // 全部买下需要的钱
double avg; // 单价
} Warehouse;
// qsort 排序函数
int cmpAvg(const void *ca, const void *cb){
return (*(Warehouse*)ca).avg > (*(Warehouse*)cb).avg;
}
int main(){
double M;
int N, i;
while (scanf("%lf %d", &M, &N) != EOF){
if (N == -1) continue;
// 输入数据,排序
double ans = 0;
Warehouse ware[N];
for (i = 0; i < N; ++i){
scanf("%lf %lf", &ware[i].java, &ware[i].food);
ware[i].avg = ware[i].food / ware[i].java;
}
qsort(ware, N, sizeof(Warehouse), cmpAvg);
// 从单价低的货仓开始买
// 直到全部买完或者不足以买下一个完整的货仓为止
for (i = 0; i < N; ++i){
if (ware[i].food < M){
M -= ware[i].food;
ans += ware[i].java;
} else break;
}
// i < N 说明没有全部买完
if (i < N)
ans += ware[i].java * M / ware[i].food;
printf("%.3lf\n", ans);
}
return 0;
}