题目来源:杭电acm1009
问题 - 1009 (hdu.edu.cn)http://acm.hdu.edu.cn/showproblem.php?pid=1009
问题描述
胖老鼠准备了M磅的猫粮,准备与守卫他最喜欢的食物JavaBean的仓库的猫进行交易。仓库有N个房间。第 i 个房间包含 J[i] 磅的 JavaBeans,需要 F[i] 磅的猫粮。FatMouse 不必交易房间里的所有 JavaBeans,相反,如果他支付 F[i]* a% 磅的猫粮,他可能会得到 J[i]* a% 磅的 JavaBeans。这里 a 是一个实数。现在他正在给你布置这个作业:告诉他他能获得的最大 JavaBeans 数量。
输入
输入由多个测试用例组成。每个测试用例都以包含两个非负整数 M 和 N 的行开头。然后是 N 行,每行分别包含两个非负整数 J[i] 和 F[i]。最后一个测试用例后面跟着两个 -1。所有整数都不大于 1000。
输出
对于每个测试用例,在一行中打印一个精确到小数点后 3 位的实数,这是 FatMouse 可以获得的最大 JavaBean 数量。
示例输入
5 3 7 2 4 3 5 2 20 3 25 18 24 15 15 10 -1 -1
示例输出
13.333 31.500
题目分析:
这是一道典型的贪心算法题目。题目中,我们需要帮助FatMouse用有限的猫粮去获取尽可能多的JavaBeans。每个房间都可以用一定比例的猫粮换取一定比例的JavaBeans,我们需要找出最优的换取比例,使得FatMouse可以获得最大的JavaBeans数量。
解题思路:
定义一个mouse的结构体数组,然后利用qsort函数(快速排序)对mouse进行降序排序,然后找出单位价值最大的去交换,直到猫粮不够完整交换整个房间javabean,这时候用比例去交换。
注意事项:
在实现上述思路的过程中,需要注意浮点数的精度问题(如果用的是int类型就要注意一下)以及如何在猫粮不足以换取下一个房间的JavaBeans时,调整单位比例以获得最大的JavaBeans数量。
代码如下:
#include <stdio.h>
#include <stdlib.h>
//定义房间属性
struct s {
double j; // javabean
double f; // 猫粮
double d; // 单位价值
} mouse[1000] = {0};
//定义排序方式cmp
int cmp(const void *a, const void *b) {
struct s *mouse1 = (struct s *)a;
struct s *mouse2 = (struct s *)b;
if (mouse1->d > mouse2->d) {
return -1;
} else if (mouse1->d < mouse2->d) {
return 1;
} else {
return 0;
}
}
int main() {
int n;
double max,m;
while (scanf("%lf %d", &m, &n) != EOF) {
if (m == -1 && n == -1) {
break;
}
for (int i = 0; i < n; i++) {
scanf("%lf %lf", &mouse[i].j, &mouse[i].f);
mouse[i].d = mouse[i].j / mouse[i].f;
}
qsort(mouse, n, sizeof(struct s), cmp);
max = 0;
for (int k = 0; k < n; k++) {
if (m >= mouse[k].f) {
m -= mouse[k].f;
max += mouse[k].j;
} else {
max += mouse[k].d * m;
break;
}
}
printf("%.3lf\n", max);
}
return 0;
}
小小总结:
qsort函数yyds!!