题目描述
Yougth现在有n个物品的重量和价值分别是Wi和Vi,你能帮他从中选出k个物品使得单位重量的价值最大吗?
输入
有多组测试数据
每组测试数据第一行有两个数n和k,接下来一行有n个数Wi和Vi。
(1<=k=n<=10000) (1<=Wi,Vi<=1000000)
输出
输出使得单位价值的最大值。(保留两位小数)
样例输入
3 2
2 2
3 2
2 1
样例输出
0.80
题解:
二分+贪心
二分
v
[
i
]
/
w
[
i
]
v[i]/w[i]
v[i]/w[i]的平均值(记为
x
x
x),边界
(
r
)
(r)
(r)就是所有物品
x
x
x的最大值。然后用贪心算法检查:将第
i
i
i个
(
0
<
=
i
<
n
)
(0<=i<n)
(0<=i<n)物品的价值减去
x
x
x(这个值记为
y
[
i
]
y[i]
y[i]),再将
y
y
y数组排序,最后从大到小循环
k
k
k个,求和(和记为
s
u
m
sum
sum),如果
s
u
m
>
=
0
sum>=0
sum>=0则返回
t
r
u
e
true
true,记录答案,最后返回
l
l
l(上边界)即可
C o d e : Code: Code:
#include<bits/stdc++.h>
#define d double
using namespace std;
const int N=10005;
int w[N],v[N],n,c;
d y[N];
int chack(d x)
{
for(int i=0;i<n;i++)y[i]=v[i]-x*w[i];
sort(y,y+n);
d sum=0;
for(int i=0;i<c;i++)sum+=y[n-i-1];
return sum>=0;
}
d bin(d enf)
{
d l=0,r=enf,mid;
for(int i=0;i<100;i++)
{
mid=(l+r)/2;
if(chack(mid))l=mid;
else r=mid;
}
return l;
}
int main()
{
while(~scanf("%d%d",&n,&c))
{
d ma=0;
for(int i=0;i<n;i++)
{
scanf("%d%d",&w[i],&v[i]);
d cmp=v[i]/w[i];
if(cmp>ma)ma=cmp;
}
printf("%.2lf\n",bin(ma));
}
return 0;
}