杭电--2187 悼念512汶川大地震遇难同胞——老人是真饿了(贪心)

版权声明:本文为博主原创文章,欢迎各位转载,但请带上本文地址。 https://blog.csdn.net/LD_1090815922/article/details/65946976

本题连接:点击打开链接

 

悼念512汶川大地震遇难同胞——老人是真饿了

 


对于幸存的灾民来说,最急待解决的显然是温饱问题,救灾部队一边在组织人员全力打通交通,一边在组织采购粮食。现在假设下拨了一定数量的救灾经费要去市场采购大米(散装)。如果市场有m种大米,各种大米的单价和重量已知,请问,为了满足更多灾民的需求,最多能采购多少重量的大米呢?

 

 

Input

输入数据首先包含一个正整数C,表示有C组测试用例,每组测试用例的第一行是两个整数n和m(0<n<=1000,0<m<=1000),分别表示经费的金额和大米的种类,然后是m行数据,每行包含2个整数p和h(1<=p<=25,1<=h<=100),分别表示单价和对应大米的重量。

 

 

Output

对于每组测试数据,请输出能够购买大米的最多重量(你可以假设经费买不光所有的大米)。
每个实例的输出占一行,保留2位小数。

 

 

Sample Input


 

1 7 2 3 3 4 4

 

 

Sample Output


 

2.33

 

 

Author

lcy

 

 

Source

2008-06-18《 ACM程序设计》期末考试——四川加油!中国加油!

 

 

Recommend

lcy   |   We have carefully selected several similar problems for you:  1050 2037 1051 1800 2570 



PS : 这是本人写的第一个贪心算法的题目,已经做过很久了,当时也不知道使用贪心算法,直接按思路敲了代码,所以代码比较简陋,排序都用的还是冒泡法,大家可适当变通,不过建议初学者还是自己手动写排序方法,不要用C++里面的函数,快排也用手写。等熟练之后再调用函数解答。

 

解题思路:既然要求能够购买大米的最多重量,那么求的肯定是最优解,先进行各种大米的单价从低完高排序,然后再按顺序依次购买大米,从而可得最优解。贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题他能产生整体最优解或者是整体最优解的近似解。

 

代码:

#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
    int c,m,money;
    scanf("%d",&c);
    while(c--)
    {
        int a[1001],b[1001];   //单价用a数组来装,重量用b数组来装,注意数组开大一点
        int p,t,i,j;
        double k=0;
        scanf("%d%d",&money,&m);
        {
            for(i=0; i<m; i++)
                scanf("%d%d",&a[i],&b[i]);
            for(j=0; j<m; j++)             //既然是贪心算法,就必须得用到排序了
                for(i=0; i<m-j-1; i++)
                    if(a[i]>a[i+1])
                    {
                        t=a[i];
                        a[i]=a[i+1];
                        a[i+1]=t;
                        t=b[i];
                        b[i]=b[i+1];
                        b[i+1]=t;
                    }
            p=money;                 //先用p临时保存一下money的值。
            for(i=0; i<m; i++)
            {
                money=money-a[i]*b[i];  //尝试将第i类大米全部购买完
                {

                    if(money<0)         //判断在将第i类大米全部购买完后是否还有余额
                    {
                        k=k+(p*1.0)/a[i];       //不能买完第i类大米,就购买能够买的最大重量,然后退出循环
                        break;
                    }
                    else
                        k=k+b[i];               //否则就继续购买
                    p=p-a[i]*b[i];
                }
            }
            printf("%.2f\n",k);
        }
    }
    return 0;
}


 

展开阅读全文

没有更多推荐了,返回首页