题目描述
阿里走进了装满宝藏的藏宝洞。藏宝洞里面有N(N≤100)堆金币,第i堆金币的总重量和总价值分别是mi,vi(1≤mi,vi≤100)。阿里有一个承重量为T(T≤1000)的背包,但并不一定有办法将全部的金币都装进去。他想装走尽可能多价值的金币。所有金币都可以随意分割,分割完的金币重量价值比(也就是单位价格)不变。请问阿里最多可以拿走多少价值的金币?
输入格式
第一行两个整数N,T。
接下来N行,每行两个整数mi,vi。
输出格式
一个实数表示答案,两位小数
样例
输入样例
4 50
10 60
20 100
30 120
15 45
输出样例
240.00
试题分析
根据vi/mi=性价比,根据性价比由高到低装走,能完全装走则全装,不能完全装走则装满。
参考代码
#include<bits/stdc++.h>
using namespace std;
struct Node{
int m;//金币堆质量;
int v;//金币堆价值;
}coin[105];//金币堆结构体;
int main(){
int N,T;//N堆金币,T容量的背包;
double temp=0;//金币放入背包的价值;
double t[105];//性价比数组;
cin>>N>>T;
for(int i=0;i<N;i++){
cin>>coin[i].m>>coin[i].v;
t[i]=double(coin[i].v)/double(coin[i].m);
//t[i]为性价比,为浮点数;
}
for(int i=0;i<N;i++){
//冒泡排序,将性价比高的调到前面;
for(int j=0;j<N;j++){
if(t[j]<t[j+1]){
swap(t[j],t[j+1]);
swap(coin[j],coin[j+1]);
}
}
}
int content=0;//金币放入背包的质量;
for(int i=0;i<N;i++){
if(content+coin[i].m<T){//加上第i堆<T;
content+=coin[i].m;
temp +=double(coin[i].v); //未装满,循环;
}
else if(content+coin[i].m==T){//加上第i堆=T;
content+=coin[i].m;
temp +=double(coin[i].v);
break;//已经装满,跳出循环;
}
else{//加上第i堆>T;
temp=temp+double((T-content)*t[i]);
content=T;
break;//已经装满,跳出循环;
}
}
cout<<fixed<<setprecision(2)<<temp;
return 0;
}