poj 2976(二分搜索+最大化平均值)

传送门:Problem 2976

参考资料:

  [1]:http://www.hankcs.com/program/cpp/poj-2976-dropping-tests-problem-solution-challenge-programming-contest.html

  [2]:http://www.cnblogs.com/demian/p/7498407.html

有感而发:

  太晚了,身心疲惫,如果明天有空的话,再写上自己对于此题的理解吧,真是个充实愉快的一天啊。

  对了,今天是我们学校70周年校庆,校庆再图书馆前的广场举行,声音震天响,听到外面的热闹声,在和我一个人奋斗相对比,心中难免有些没落,自己选择的ACM,再苦再难也要扛着。

  今天莫名地想到,下一个10周年校庆,我会以何种身份出现在学校呢?

                                  2018.10.17  21:54

AC代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 #define ll long long
 6 #define INF 0x3f3f3f3f
 7 const int maxn=1e3+50;
 8 
 9 int n,k;
10 struct Node
11 {
12     int a,b;
13 }test[maxn];
14 double x;//搜索过程中的准确率
15 //按照对准确率的贡献从小到大排序
16 bool cmp(Node _a,Node _b)
17 {
18     return _a.a-x*_a.b > _b.a-x*_b.b;
19 }
20 //判断是否能获得大于 mid 的准确率
21 bool Check(double mid)
22 {
23     x=mid;
24     sort(test+1,test+n+1,cmp);
25     long long sumA=0;
26     long long sumB=0;
27     for(int i=1;i <= n-k;++i)//去掉后 k 个数后计算准确率
28         sumA += test[i].a,sumB += test[i].b;
29     return 1.0*sumA/sumB >= x;
30 }
31 void Solve()
32 {
33     double l=0,r=1;//准确率的范围为 [l,r)
34     for(int i=1;i <= 100;++i)
35     {
36         double mid=(l+r)/2;
37         if(Check(mid))//如果满足条件,则准确率的范围变为[mid,r)
38             l=mid;
39         else//反之,变为[l,mid)
40             r=mid;
41     }
42     l += 0.005;
43     printf("%d\n",(int)(l*100));
44 }
45 int main()
46 {
47     while(scanf("%d%d",&n,&k), n || k)
48     {
49         for(int i=1;i <= n;++i)
50             scanf("%d",&test[i].a);
51         for(int i=1;i <= n;++i)
52             scanf("%d",&test[i].b);
53         Solve();
54     }
55 }
View Code

猜你喜欢

转载自www.cnblogs.com/violet-acmer/p/9807411.html
今日推荐