链接:https://www.nowcoder.com/acm/contest/93/I
来源:牛客网
题目描述
wyh学长现在手里有n个物品,这n个物品的重量和价值都告诉你,然后现在让你从中选取k个,问你在所有可能选取的方案中,最大的单位价值为多少(单位价值为选取的k个物品的总价值和总重量的比值)
输入描述:
输入第一行一个整数T(1<=T<=10)
接下来有T组测试数据,对于每组测试数据,第一行输入两个数n和k(1<=k<=n<=100000)
接下来有n行,每行两个是a和b,代表这个物品的重量和价值
输出描述:
对于每组测试数据,输出对应答案,结果保留两位小数
示例1
输入
1 3 2 2 2 5 3 2 1
输出
0.75
说明
对于样例来说,我们选择第一个物品和第三个物品,达到最优目的
做法:
二分,对于每一个答案C,有 s[i] = w[i]-c*v[i]
排序,取最大前k个,如果大于等于0则可行,否则不可行
代码:
#include<iostream> using namespace std; #include<cstring> #include<cstdio> #include<cstdlib> #include<algorithm> struct Thing{ double w,v; double dj; double s; void count(double c){ s = w-c*v; } bool operator<(const Thing &pt)const{ return s>pt.s; } }; int n,m; Thing thing[110000]; int check(double c){ for(int i=0;i<n;i++){ thing[i].count(c); } sort(thing,thing+n); double sum = 0; for(int i=0;i<m;i++) sum+=thing[i].s; if(sum>0) return 1; else return 0; } void deal(){ scanf("%d%d",&n,&m); for(int i=0;i<n;i++){ scanf("%lf%lf",&thing[i].v,&thing[i].w); thing[i].dj = thing[i].w/thing[i].v; } double l = 0, r = 1e9; while(l<=r){ double mid = (l+r)/2; int ans = check(mid); if(ans==1) l=mid+0.0001; else r=mid-0.0001; } printf("%.2f\n",r); } int main(){ int t; scanf("%d",&t); while(t--) deal(); return 0; }