FatMouse‘ Trade

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.(FatMouse准备了M磅的猫粮,准备和看守仓库的猫交易,仓库里有他最喜欢的食物JavaBean。 仓库有N个房间。第一个房间有J磅的咖啡豆,需要F磅的猫粮。FatMouse不必用房间里的所有咖啡豆进行交易,相反,如果他支付F[i]* a%磅的猫粮,他可能会得到J[i]* a%磅的咖啡豆。这里a是实数。现在他给你布置了这个作业:告诉他,他能获得的最大数量的咖啡豆。)
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.
(输入由多个测试用例组成。每个测试用例以一行包含两个非负整数M和N开始,然后是N行,每一行分别包含两个非负整数J[i]和F[i]。最后一个测试用例后面是两个1。所有整数都不大于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.(对于每个测试用例,在一行中打印一个精确到小数点后3位的实数,这是FatMouse可以获得的咖啡豆的最大数量。)

代码

#include <stdio.h>
#include <stdlib.h>
#define MAX 1000
struct food{
    
    
    int j,f;  || 定义j表示咖啡豆,f表示猫粮。
    double p;  || p表示咖啡豆和猫粮的比例,用双精度更精确。
}food_N[1001];  || 定义个数组表示房间数。
 
int main(void)
{
    
    
    int m,n,i;  || 定义m表示胖鼠有点猫粮数量,n表示总的房间数,i表示房间号。
    while(scanf("%d%d",&m,&n) && (m!=-1 || n!=-1))
    {
    
    
        double sum=0.0;  || 最开始胖鼠是0个咖啡豆。
        struct food temp; 
        for( i=0;i<n;i++)   || 从房间号为0开始循环探索,每次加一。
        {
    
    
            scanf("%d%d",&food_N[i].j,&food_N[i].f);  || 输入j,f 。这里表示第i个房间有j个咖啡豆,且需要f个猫粮兑换。
            food_N[i].p=(double)food_N[i].j/food_N[i].f;  || 第i个房间咖啡豆和需要兑换猫粮的比例。
        }
        for(i=0;i<n;i++)
        {
    
    
            for(int k=i;k<n;k++)  || 定义一个k,k的出现打破了现在的咖啡豆和猫粮比例的排序
            {
    
    
                if(food_N[i].p<food_N[k].p) 
                {
    
    
                    temp=food_N[i];
                    food_N[i]=food_N[k];
                    food_N[k]=temp;  ||这里采用了一个换数的方法更改了排序,也就是冒泡排序。
                }
            }
        }
        for(int i=0;i<n;i++)  
        {
    
    
            if(m>food_N[i].f)  || 在探索到一个房间时,若胖鼠手上的猫粮大于该房间需要兑换的猫粮数。
            {
    
    
                sum+=food_N[i].j;  || 则直接交换。
                m-=food_N[i].f;   || 然后减去兑换的数量。
            }
            else
            {
    
    
                sum+=food_N[i].p*m;  || 若是不够,则按比例兑换。
                break;
            }
        }
        printf("%.3lf\n",sum);
    }
    return 0;
}

思路
1、由于每个房间都包含了小老鼠需要付出的代价,则需要找出咖啡豆和猫粮比例最大的进行交换,这样才能得到的更多的猫粮,这样就得探索每个房间,然后进行比例从大到小的排序,如果最后的代价不足以获得这个房间内的所有咖啡豆,则按比例获得代价相应的咖啡豆。

注意点
1、temp不是C语言的关键字,也不是任何函数或命令字,只是用户定义的一个普通变量,当然数据类型用户也可以随意定义。
2、贪心算法总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。当然,希望贪心算法得到的最终结果也是整体最优的。虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。

猜你喜欢

转载自blog.csdn.net/weixin_54501632/article/details/114682986
今日推荐