POJ 3111 K Best 二分 最大化平均值
Posted cn_XuYang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 3111 K Best 二分 最大化平均值相关的知识,希望对你有一定的参考价值。
1.题意:给一共N个物品,每个物品有重量W,价值V,要你选出K个出来,使得他们的平均单位重量的价值最高
2.分析:题意为最大化平均值问题,由于每个物品的重量不同所以无法直接按单位价值贪心,但是目标值有界且能判断与最后答案的大小关系,所以用二分来做
3.代码:
1 # include <iostream> 2 # include <cstdio> 3 # include <cmath> 4 # include <algorithm> 5 using namespace std; 6 const double eps=1e-8; 7 const int MAXN=100005; 8 int N,K; 9 int sgn(double x) 10 { 11 if(fabs(x)<eps) return 0; 12 if(x>0) return 1; 13 else return -1; 14 } 15 struct Node 16 { 17 int n; 18 double v,w; 19 Node(){} 20 Node(int nn,double vv,double ww) 21 { 22 23 n=nn; 24 v=vv; 25 w=ww; 26 } 27 }L[MAXN]; 28 struct OUT 29 { 30 int n; 31 double sum; 32 OUT(){} 33 OUT(int nn,double ss) 34 { 35 n=nn; 36 sum=ss; 37 } 38 }; 39 bool cmp(OUT x,OUT y) 40 { 41 return sgn(y.sum-x.sum)<0; 42 } 43 void Init() 44 { 45 double a,b; 46 for(int i=0;i<N;i++) 47 { 48 scanf("%lf%lf",&a,&b); 49 L[i]=Node(i+1,a,b); 50 } 51 } 52 void Solve() 53 { 54 OUT O[MAXN]; 55 double l=0.0; 56 double r=1e7; 57 while(sgn(r-l)!=0) 58 { 59 double mid=l+(r-l)/2.0; 60 for(int i=0;i<N;i++) 61 O[i]=OUT(L[i].n,L[i].v-L[i].w*mid); 62 sort(O,O+N,cmp); 63 double temp=0; 64 for(int i=0;i<K;i++) 65 temp+=O[i].sum; 66 if(sgn(temp)<0) r=mid; 67 else l=mid; 68 } 69 for(int i=0;i<K-1;i++) 70 printf("%d ",O[i].n); 71 printf("%d\n",O[K-1].n); 72 } 73 int main() 74 { 75 while(scanf("%d%d",&N,&K)!=EOF) 76 { 77 Init(); 78 Solve(); 79 } 80 return 0; 81 }
以上是关于POJ 3111 K Best 二分 最大化平均值的主要内容,如果未能解决你的问题,请参考以下文章