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
",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 }
原文地址:https://www.cnblogs.com/cnXuYang/p/7253256.html