题目描述
商店里有n种饮料,第i种饮料有mi毫升,价格为wi。 小明现在手里有x元,他想喝尽量多的饮料,于是向你寻求帮助,怎么样买才能喝的最多。 请注意,每一种饮料都可以只买一部分。
输入描述:
有多组测试数据。 第一行输入两个非负整数x和n。 接下来n行,每行输入两个整数,分别为mi和wi。 所有数据都不大于1000。 x和n都为-1时程序结束。
输出描述:
请输出小明最多能喝到多少毫升的饮料,结果保留三位小数。
示例
输入
233 6
6 1
23 66
32 23
66 66
1 5
8 5
-1 -1
输出
136.000
思路
-
小明要想喝的最多饮料的话,应优先选择性价比最高的,即每毫升的价格最低的饮料先喝。
-
利用sort排序,比较每毫升的饮料价格,从低到高排序。然后一个一个喝,直到金额为0为止,这样才能保证喝到最多饮料。
具体实现
#include<bits/stdc++.h>
using namespace std;
struct node{
double mi,wi; //mi为毫升 wi表示价格
}p[100];
bool cmp(struct node a, struct node b){
return a.wi/a.mi < b.wi/b.mi; //每毫升的价格按从小到大排序
}
int main(){
int x,n; //x表示金额总数,n表示饮料总数
while(cin>>x>>n){
if(x == -1 && n == -1) break;
for(int i=0; i<n; i++) //输入饮料毫升和价格
cin>>p[i].mi>>p[i].wi;
sort(p,p+n,cmp); //排序
double ans=0; //存放买的饮料的毫升
for(int i=0; i<n; i++){
if(x>=p[i].wi){ //如果钱够买这款饮料
ans+=p[i].mi;
x-=p[i].wi;
}else{ //如果钱不够买这款饮料
ans = p[i].mi * x/p[i].wi;
break; //金额已花完
}
}
printf("%.3lf\n",ans);
}
return 0;
}
小结
-
贪心算法:追求当前的最优解,从而得到全局最优解。即不从整体最优加以考虑,只做出在某种意义上的局部最优解。
-
使用贪心算法的时候,往往需要先按某个特性排好序,也就是说贪心一般和sort一起使用。