题目来源:http://ybt.ssoier.cn:8088/problem_show.php?pid=1225
1225:金银岛
时间限制: 1000 ms 内存限制: 65536 KB
提交数: 2388 通过数: 1225
【题目描述】
某天KID利用飞行器飞到了一个金银岛上,上面有许多珍贵的金属,KID虽然更喜欢各种宝石的艺术品,可是也不拒绝这样珍贵的金属。但是他只带着一个口袋,口袋至多只能装重量为w的物品。岛上金属有ss个种类, 每种金属重量不同,分别为n1,n2,...,nsn1,n2,...,ns,同时每个种类的金属总的价值也不同,分别为v1,v2,...,vsv1,v2,...,vs。KID想一次带走价值尽可能多的金属,问他最多能带走价值多少的金属。注意到金属是可以被任意分割的,并且金属的价值和其重量成正比。
【输入】
第1行是测试数据的组数kk,后面跟着kk组输入。
每组测试数据占3行,第1行是一个正整数w(1≤w≤10000)w(1≤w≤10000),表示口袋承重上限。第2行是一个正整数s(1≤s≤100)s(1≤s≤100),表示金属种类。第3行有2s2s个正整数,分别为n1,v1,n2,v2,...,ns,vsn1,v1,n2,v2,...,ns,vs分别为第一种,第二种,...,第ss种金属的总重量和总价值(1≤ni≤10000,1≤vi≤10000)(1≤ni≤10000,1≤vi≤10000)。
【输出】
kk行,每行输出对应一个输入。输出应精确到小数点后22位。
【输入样例】
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 }