DreamJudge-1478-喝饮料
1.题目描述
Time Limit: 1000 ms
Memory Limit: 256 mb
商店里有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
题目来源
云南大学机试题
2.题解
2.1 贪心算法
思路
我先开始理解错了题意,以为一种饮料能够购买多次,其实这里只能购买一次!!!
考虑优先购买 ml/价格 性价比最高的饮料, 由于请注意,每一种饮料都可以只买一部分。,保证我们的每一步都是最优解,否则不一定成立!!!
代码
#include<bits/stdc++.h>
using namespace std;
class Drink{
public:
int m, w;
Drink(){}
Drink(int ml, int price):m(ml), w(price){}
bool operator<(const Drink& other)const{
return other.w * m > w * other.m;
}
};
int main(){
while(true){
int n, w;
cin >> w >> n;
if(w == -1 && n == -1) break;
vector<Drink> drinks(n); // 这里需要初始化空构造函数
for(int i = 0; i < n; i++){
int ml, price;
cin >> ml >> price;
drinks[i] = Drink(ml, price);
}
sort(drinks.begin(), drinks.end());
double ans = 0;
for(Drink drink : drinks){
if(w >= drink.w){
ans += drink.m;
w -= drink.w;
}else{
ans += static_cast<double>(w) * drink.m / drink.w;
break;
}
}
printf("%.3lf\n", ans);
}
return 0;
}