HDU 1009 FatMouse' Trade

本文介绍了一个利用贪心算法解决的食物交换问题。老鼠使用有限的猫粮换取最大数量的老鼠粮,通过计算各仓库的交换比例并排序来实现最优选择。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

FatMouse' Trade

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 104641    Accepted Submission(s): 36538

Problem Description

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的猫粮想和猫换老鼠粮下面就是N行数据表示每个仓库里所有的老鼠粮和换完需要的猫粮求最多能换多少老鼠粮食
我的大题思路就是贪心算法先将每个仓库的性价比算出来然后排序每次拿最高性价比的不够的时候再单独算能拿多少

改了几次还是一直WA好像不是精度问题
下面是我写的代码希望有大佬帮忙指下错误测试数据和特殊数据我都试了没问题(我不是搞算法的不要在意集合数组优化这些细节)

import java.util.Comparator;
import java.util.LinkedList;
import java.util.Scanner;

//贪心算法题目大体意思就是老鼠和猫换食物
//老鼠有M的食物有N行数据就是N个仓库每个仓库有J[I]的粮食
//N行数据表示老鼠想要换掉这些食物所需要的食物交换树木
//很明显我们可以用两者食物数量的比值进行排序最大的就是老鼠换来最划算的
public class Problem1009 {
    public static void main(String[] args) throws Exception{
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            double M = sc.nextDouble();
            double N = sc.nextDouble();
            if(M==-1&&N==-1) return;
            LinkedList<Node> proprotion = new LinkedList<Node>();
            //数组的初始化
            for(int i=0;i<N;i++){
                proprotion.addLast(new Node(sc.nextDouble(),sc.nextDouble()));
            }
            //对性价比集合进行排序老鼠能得到的性价比最高的就是
            proprotion.sort(new Comparator<Node>() {
                @Override
                public int compare(Node o1, Node o2) {
                    if(o1.value>o2.value) return 1;
                    if(o1.value==o2.value) return 0;
                    /*else if(o1.value==o2.value){
                        仔细考虑后这段好像没必要
                        //相等的话就要比较消耗的猫粮的多少了给予的猫粮越少就越往后
                        if(o1.catFood<o2.catFood) return 1;
                        else if(o1.catFood==o2.catFood) return 0;
                        else return -1;
                    }*/
                    else return -1;
                }
            });
            //开始交易
            double result = 0;
            while (M>0){
                Node temp = proprotion.removeLast();
                if(M>temp.catFood){
                    result+=temp.mouseFood;
                    M-=temp.catFood;
                }else {
                    /*double tempPro = M/temp.catFood; 以为是精度问题但最终还是错误
                    result+=temp.mouseFood*tempPro;*/
                    result+=temp.mouseFood*M/temp.catFood;
                    M=0;
                }
            }
            String lastResult = String.format("%.3f",result);
            System.out.println(lastResult);
        }
    }
}
class Node{
    double mouseFood;
    double catFood;
    double value;
    Node(double mouseFood,double catFood){
        this.value = mouseFood/catFood;
        this.mouseFood = mouseFood;
        this.catFood = catFood;
    };
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值