poj 2976(01规划)

题意:

 给定n个二元组(a,b),删除k个二元组,使得剩下的a元素之和与b元素之和的比率最大(比率最后乘100输出)

ai<=bi

设 (a1+a2+...an)/(b1+b2+..bn)=m;

则有∑(ai-m*bi)=0

显然m是在0,1之间的。(ai<=bi)

故可二分查找m。

 1 // File Name: 2976.cpp
 2 // Author: Missa
 3 // Created Time: 2013/3/16 星期六 15:37:33
 4 
 5 #include<iostream>
 6 #include<cstdio>
 7 #include<cstring>
 8 #include<algorithm>
 9 #include<cmath>
10 #include<queue>
11 #include<stack>
12 #include<string>
13 #include<vector>
14 #include<cstdlib>
15 #include<map>
16 #include<set>
17 using namespace std;
18 #define CL(x,v) memset(x,v,sizeof(x));
19 #define R(i,st,en) for(int i=st;i<en;i++)
20 #define ll long long
21 #define inf 0x3f3f3f3f
22 
23 const int maxn = 1e3+5;
24 int n,k;
25 struct node
26 {
27     double a,b,c;
28 }p[maxn];
29 bool cmp(const node &aa,const node &bb)
30 {
31     return aa.c>bb.c;
32 }
33 bool check(double m)
34 {
35     R(i,0,n)
36         p[i].c=p[i].a-p[i].b*m;
37     sort(p,p+n,cmp);
38     //R(i,0,n)
39     //    printf("%lf %lf %lf\n",p[i].a,p[i].b,p[i].c);
40     //printf("\n");
41     double ans=0.0;
42     R(i,0,n-k)
43         ans+=p[i].c;
44     if(ans<0.0)
45         return false;
46     else
47         return true;
48 }
49 int main()
50 {
51     while(~scanf("%d%d",&n,&k))
52     {
53         if(!n && !k) break;
54         R(i,0,n)
55             scanf("%lf",&p[i].a);
56         R(i,0,n)
57             scanf("%lf",&p[i].b);
58         double low=0.0,high=1.0;
59         double mid;
60         while(high-low>1e-8)
61         {
62             mid=(high+low)/2.0;
63             //cout<<mid<<endl;
64             if(check(mid))
65                 low=mid;
66             else
67                 high=mid;
68         }
69         printf("%.0f\n",100*mid);
70     }
71     return 0;
72 }

 

posted @ 2013-03-16 16:11  Missa  阅读(263)  评论(0编辑  收藏  举报