Java编写胖老鼠的交易,猫鼠交易(贪心) HDU 1009 FatMouse' Trade

本文介绍了一个关于贪心算法的应用实例——猫鼠交易。题目要求使用贪心策略,通过比较每单位猫食所能换取的JavaBean数量,找到最优交易策略,以获取最多的JavaBean。博主详细解析了问题并提供了C++代码实现,强调了贪心算法在解决此类问题中的有效性。
摘要由CSDN通过智能技术生成

猫鼠交易(贪心) HDU 1009 FatMouse’ 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.

Input

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.

Output

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.

Sample Input

5 3

7 2

4 3

5 2

20 3

25 18

24 15

15 10

-1 -1

Sample Output

13.333

31.500

这里我就参考别人的翻译了一下:

猫鼠交易

题目描述:

胖老鼠准备了M榜的猫食,想要用来与守卫藏有他最爱的JavaBean的仓库的猫猫们进行交易。

仓库有N个房间,第i个房间里面有J[i]榜的JavaBean,同时需要F[i]榜的猫食才能换取。

胖老鼠可以只按比例换取JavaBean而不是换取整个房间的JavaBean。

现在它把交易计划交给你来处理:告诉它,它最多能得到多少榜JavaBean。

输入说明:

允许多次案例输入,每个案例的第一行为两个无符号整数 M和N。

接着是N行输入,每一行包含无符号整数J[i]和F[i]。

程序输入以两个-1结束。

所有的整数都不会超过1000。

输出说明:

对于每个案例,输出一个保留三位有效数字的实数,用来表示这个案例中胖老鼠最大能获得的JavaBean。

个人分析:

上面我把这个题的题意解释了一遍,采用贪心的思考问题方法

即“做出的是在某种意义上的局部最优解”,对于本题来说,局部最优解就是整体最优解,因此采用贪心法。

很显然,要采用结构体做,那么我们申明结构体一般还要写好cmp方法,并且是重载的cmp方法 具体如下:

struct node

{

int j;

int f;

double rate;

}fm[1008];

int cmp(node x,node y)

{

return x.rate>y.rate;

}

要使JavaBean最大,那就得要每一榜猫食换取尽可能多的JavaBean。

所以 先计算出每一个房间的 单位食物能换取的JavaBean,即 rate[i] = J[i]/F[i]。

接着 对结构体fm(肥鼠)排序,rate[i]越大,JavaBean换的越多

剩余的JavaBean小到不足以换取整个房间的JavaBean时,选择按比例换取JavaBean。(也就是剩余的m去乘rate[i]那个比例) 如下关键代码:

sort(fm,fm+n,cmp);

for(int i=0;i

{

if(m>=fm[i].f)

{

m-=fm[i].f;

sum+=fm[i].j;

}

else

{

sum+=fm[i].rate*m;

break;

}

}

对以上代码解释:

m是这只肥鼠所有的猫粮 通过比例排序(从大到小排)比例大的那么我们获得的豆子也就越多 只要m>=fm[i].f 那么我们可以获得全部的豆子 剩余的m不足以获得全部的豆子我们用比例来拿 sum+=fm[i].rate*m; 但是注意拿了之后要break 因为已经拿完了 不然还会继续循环的。。。这里要注意

个人感受:

这个贪心也是我第一次遇到,觉得很不可思议,因为这个题是通过比例来求解的,看来要走的路还挺长的,虽然走的很慢,但还是要坚持下去!

具体代码如下:

4183c9262fd375984d0aef9d565ab2fa.png

#include

#include

#include

using namespace std;

struct node

{

int j;

int f;

double rate;

}fm[1008];

int cmp(node x,node y)

{

return x.rate>y.rate;

}

int main()

{

int m,n;

while(cin>>m>>n&&m!=-1&&n!=-1)

{

double sum=0;

for(int i=0;i

{

cin>>fm[i].j>>fm[i].f;

fm[i].rate=(double)fm[i].j/fm[i].f;

}

sort(fm,fm+n,cmp);

for(int i=0;i

{

if(m>=fm[i].f)

{

m-=fm[i].f;

sum+=fm[i].j;

}

else

{

sum+=fm[i].rate*m;

break;

}

}

printf("%.3lf\n",sum);

}

return 0;

}

学如逆水行舟,不进则退

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值