题目链接:https://www.nowcoder.com/acm/contest/93/I
题意: n件物品,都有各自的val、weight,问挑选k件物品的单位重量的价值最大; |
flag:0-1整数规划问题
推荐看:https://blog.csdn.net/hzoi_ztx/article/details/54898323
最开始二分区间为[ 0 , max { val[i]/weight[i] | i∈[0,n) } ];
判断mid,排序找出前k个最大的val[i] - mid*weight[i],其和是否大于小于ESP(1e-7);
就最终找到的mid使得前k个最大的val[i] - mid*weight[i],绝对值小于ESP(1e-7),此时mid为要找的最大单位价值;
时间复杂度O(n*logn*log r)
/***********
0-1整数规划问题
************/
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <math.h>
#include <vector>
using namespace std;
const int Size=1e5+7;
const double eas=1e-7;
double val[Size],weight[Size];
double R[Size];
int n,k;
bool cmp(double x,double y){
return x>y;
}
int check(double r){
for(int i=0;i<n;++i)
R[i]=val[i]-r*weight[i];
sort(R,R+n,cmp);
double ans=0.0;
for(int i=0;i<k;++i)
ans+=R[i];
return (ans>=eas);
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&k);
double l=0,r=0;
for(int i=0;i<n;++i){
scanf("%lf%lf",&weight[i],&val[i]);
r=max(r,val[i]/weight[i]);
}
double mid;
while(abs(r-l)>eas){
mid=(l+r)/2;
if(check(mid))//为1即f(mid)>=0
l=mid;
else r=mid;
}
printf("%.2f\n",mid);
}
return 0;
}