题目来源:http://ybt.ssoier.cn:8088/problem_show.php?pid=1225
1225:金银岛
时间限制: 1000 ms 内存限制: 65536 KB
提交数: 2388 通过数: 1225
【题目描述】
某天KID利用飞行器飞到了一个金银岛上,上面有许多珍贵的金属,KID虽然更喜欢各种宝石的艺术品,可是也不拒绝这样珍贵的金属。但是他只带着一个口袋,口袋至多只能装重量为w的物品。岛上金属有v1,v2,...,vs。KID想一次带走价值尽可能多的金属,问他最多能带走价值多少的金属。注意到金属是可以被任意分割的,并且金属的价值和其重量成正比。
【输入】
第1行是测试数据的组数k组输入。
每组测试数据占3行,第1行是一个正整数(1≤ni≤10000,1≤vi≤10000)。
【输出】
2位。
【输入样例】
2 50 4 10 100 50 30 7 34 87 100 10000 5 1 43 43 323 35 45 43 54 87 43
【输出样例】
171.93 508.00
解析:
贪心策略:每次找性价比最高的金属放入背包。
参考代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 double q; 7 int s; 8 struct metal{ 9 double n,v,p;//p性价比 10 }a[101]; 11 bool cmp(metal a,metal b) 12 { 13 return a.p>b.p; 14 } 15 void solve() 16 { 17 int t=q; 18 double ans=0; 19 for(int i=1;i<=s;i++) 20 { 21 if(t>a[i].n) 22 { 23 ans+=a[i].v; 24 t-=a[i].n; 25 } 26 else 27 { 28 ans+=a[i].p*t; 29 t=0; 30 } 31 } 32 printf("%.2lf\n",ans); 33 } 34 int main() 35 { 36 int k; 37 cin>>k; 38 while(k--) 39 { 40 cin>>q>>s;//q背包容量,s金属种类 41 for(int i=1;i<=s;i++) 42 { 43 cin>>a[i].n>>a[i].v; 44 a[i].p=a[i].v/a[i].n; 45 } 46 sort(a+1,a+s+1,cmp); 47 48 solve(); 49 } 50 }