FatMouse准备了M磅猫粮,它想和守卫仓库的猫进行交易,因为仓库里有它最爱吃的食物Javabean。仓库里有N个房间,在第i间房间里有J[i]磅Javabean,需要用F[i]磅猫粮来进行交换。FatMouse不必买在房间里的全部Javabean,也就是说他可以给猫F[i]*a%磅猫粮,来换取J[i]*a%磅的Javabean,其中a是一个实数。现在FatMouse给您布置家庭作业,请您告诉他,他最多能够获得多少磅Javabean。
输入:
输入包含多个测试用例。每个测试用例的第一行给出两个非负整数M和N,接下来的N行每行给出两个非负整数J[i]和F[i],最后一个测试用例是两个-1,所有整数的值不超过1000。
输出:
对于每个测试用例,在一行上输出一个3位小数的实数,这个实数是FatMouse能够通过交易得到的最大数量的Javabean。
题解:贪心算法在对问题进行求解时,总是做出在当前看来是最好的选择,也就是说,不从整体最优上加以考虑,只做出在某种意义上的局部最优解,对于本题先对J[i]/ F[i]结果进行排序(比较时注意精度),然后for循环用M对Javabean进行兑换。
#include <bits/stdc++.h>
using namespace std;
bool cmp(pair<double,double> p1,pair<double,double> p2)
{
return p1.first/p1.second>p2.first/p2.second;
}
int main()
{
int m,n;
while(cin>>m>>n)
{
if(m==-1&&n==-1) break;
double j,f;
pair<double,double> pa[n];//pair数组存每组对应j,f;
for(int i=0; i<n; i++)
{
cin>>j>>f;
pa[i]= {j,f};
}
sort(pa,pa+n,cmp);//自定义排序,cmp对每组j/f的值进行从大到小排序
double sum=0;
for(int i=0; i<n; i++) //从大到小便利元素
{
if(pa[i].second<=m)//贪心思想,m不足f时,else按比例兑换
{
sum+=pa[i].first;
m-=pa[i].second;
}
else
{
sum+=m*pa[i].first/pa[i].second;
break;
}
}
printf("%.3f\n",sum);//精度3位小数
}
return 0;
}