【问题描述】
给在一个神秘的国度,有一种多拿多得的疯狂游戏,某日大壮去参赛,在规定区域内里面有 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
【数据规模】
100%的数据满足 1 ≤ N< ,mi,vi(1≤ mi,vi≤100),1 ≤ T <
【题解】
本题关键点:从大到小排序单个金币价格,贪心测略:在背包承重范围内优先选择单位价格高的金币。代码如下。
#include <iostream>
#include <iomanip>
using namespace std;
int main(){
int n,middle,weight,w,tmiddle,z;
double t;
double cost;
cin>>n>>t;
int m[n];
int v[n];
int s[n];
cost=0;
weight=0;
w=0;
tmiddle=t;
for(int i=0;i<n;i++){
cin>>m[i]>>v[i];
s[i]=v[i]/m[i];
}
for(int j=0;j<n;j++){
for(int k=j+1;k<n;k++){
if(s[k]>s[j]){
middle = s[j];
s[j]=s[k];
s[k]=middle;
//对应重量
middle = m[j];
m[j]=m[k];
m[k]=middle;
}
}
}
for(int x=0;x<n;x++){
t-=1*m[x];
if(t<0){
break;
}else{
cost+=m[x]*s[x];
w+=m[x];
z=x;
}
}
if(w<tmiddle){
for(int y=0;y<tmiddle-w;y++){
cost+=s[z+1];
}
}
cout<<fixed<<setprecision(2)<<cost<<endl;
return 0;
}