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;
}