HDU 1009 - FatMouse' Trade (部分背包问题)

题目:
肥鼠准备了 M 磅的猫粮,准备和看管仓库的猫交易,仓库里装有他最喜爱的食物 Java 豆。

仓库有 N 个房间。第 i 间房包含了 J[i] 磅的 Java 豆,需要 F[i] 磅的猫粮。肥鼠不必为了房间中的所有 Java 豆而交易,相反,他可以支付 F[i] * a% 磅的猫粮去交换得到 J[i] * a% 磅的 Java 豆。这里,a 表示一个实数。

现在他将这项任务分配给了你:请告诉他,能够获得的 Java 豆的最大值是多少。

输入
输入包含多组测试数据。

对于每组测试数据,以包含了两个非负整数 M 和 N 的一行开始。接下来的 N 行,每行相应包含了两个非负整数 J[i] 和 F[i]。

最后一组测试数据是两个 -1。所有的整数均不超过 1000。

输出
对于每组测试数据,在单独的一行中打印一个实数,精确到小数点后 3 位数,表示肥鼠能够取得的 Java 豆的最大值。

示例输入
5 3
7 2
4 3
5 2
20 3
25 18
24 15
15 10
-1 -1

示例输出
13.333
31.500
分析:先把性价比求出来(也就是Java豆/猫粮),然后sort从大到小排序,运用贪心的思想求解。

代码:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
struct food
{
    int j,f;
    double a;
}N[1010];
bool cmp(food a,food b)
{
    return a.a>b.a;
}
int main()
{
    int m,n,i;
    double s;
    while(cin>>m>>n)
    {
        s=0;
        if(m==-1 && n==-1) break;
        memset(N,0,sizeof(N));
        for(i=0;i<n;i++)
        {
            cin>>N[i].j>>N[i].f;
            if(N[i].f==0) N[i].a=10010;//若该房间花费的猫粮为0,保证先从该房间换Java豆。
            else N[i].a=1.0*N[i].j/N[i].f;

        }
        sort(N,N+n,cmp);
        for(i=0;i<n;i++)
        {
            if(N[i].f<m) 
            {
                s+=N[i].j;
                m-=N[i].f;
            }
            else
            {
                s+=m*N[i].a;
                break;
            }
        }
        printf("%.3lf\n",s);
    }
    return 0;
}
posted @ 2018-08-09 19:12  外号班长  阅读(79)  评论(0编辑  收藏  举报