POJ 2976 Dropping tests(分数规划)

http://poj.org/problem?id=2976

题意:

给出ai和bi,ai和bi是一一配对的,现在可以删除k对,使得的值最大。

 

思路:

分数规划题,可以参考《挑战程序竞赛》第144页。

枚举答案x,然后去判断是否存在$\frac{\sum a[i]}{\sum b[i]}>=x$,现在把这个式子转换一下,变成$\sum a[i]-x*\sum b[i]>=0$,这样每次贪心选择前面最大的n-k个即可,判断和x的大小关系。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<sstream>
 6 #include<vector>
 7 #include<stack>
 8 #include<queue>
 9 #include<cmath>
10 #include<map>
11 #include<set>
12 using namespace std;
13 typedef long long ll;
14 typedef pair<int,ll> pll;
15 const int INF = 0x3f3f3f3f;
16 const int maxn=1000+5;
17 const double eps=1e-10;
18 
19 int n, k;
20 int a[maxn];
21 int b[maxn];
22 double tmp[maxn];
23 
24 bool check(double x)
25 {
26     for(int i=0;i<n;i++)
27         tmp[i]=((double)a[i]-x*b[i]);
28     sort(tmp,tmp+n);
29     double sum=0;
30     for(int i=k;i<n;i++)  sum+=tmp[i];
31     if(sum>=0.0)  return true;
32     else return false;
33 }
34 
35 int main()
36 {
37     //freopen("in.txt","r",stdin);
38     while(~scanf("%d%d",&n,&k))
39     {
40         if(n==0 && k==0)  break;
41         for(int i=0;i<n;i++)  scanf("%d",&a[i]);
42         for(int i=0;i<n;i++)  scanf("%d",&b[i]);
43 
44         double ans=0;  //刚开始没给ans赋0,wa了很久。。可能会出现k=n的情况...
45         double l=0,r=1;
46         while(r-l>=eps)
47         {
48             double mid=(l+r)/2.0;
49             if(check(mid)) {ans=mid;l=mid;}
50             else r=mid;
51         }
52         printf("%d\n",(int)(ans*100+0.5));
53     }
54     return 0;
55 }
posted @ 2017-08-05 08:59  Kayden_Cheung  阅读(138)  评论(0编辑  收藏  举报
//目录