POJ2976-Dropping tests-01分数规划

关于01分数规划可以看这里,讲的很清楚:http://blog.csdn.net/hhaile/article/details/8883652

二分的思想,每次只要选取最大的N-K个d[i],如果可以使F(L)>0,就说明可以更大。

//这道题很早以前学长就挂过了,现在才学会。。。

 1 /*--------------------------------------------------------------------------------------*/
 2 //        Helica's header 
 3 //        Second Edition
 4 //        2015.11.7
 5 //
 6 #include <algorithm>
 7 #include <iostream>
 8 #include <cstring>
 9 #include <ctype.h>
10 #include <cstdlib>
11 #include <cstdio>
12 #include <vector>
13 #include <string>
14 #include <queue>
15 #include <stack>
16 #include <cmath>
17 #include <set>
18 #include <map>
19 
20 //debug function for a N*M array 
21 #define debug_map(N,M,G) printf("\n");for(int i=0;i<(N);i++)\
22 {for(int j=0;j<(M);j++){\
23 printf("%d",G[i][j]);}printf("\n");}                
24 //debug function for int,float,double,etc.
25 #define debug_var(X) cout<<#X"="<<X<<endl;
26 /*--------------------------------------------------------------------------------------*/
27 using namespace std;
28 
29 const int maxn = 1000+10;
30 const double eps = 1e-6;
31 int N,M,T,K;
32 int a[maxn],b[maxn];
33 double d[maxn];
34 bool cmp(const double &a,const double &b)
35 {    return a>b;
36 
37 }
38 
39 bool check(double mid)
40 {
41     sort(d,d+N,cmp);
42     double res = 0;
43     for(int i=0;i<N-K;i++) res += d[i];
44     if(res>0) return true;
45     else return false;
46 }
47 
48 int main()
49 {
50     while(scanf("%d%d",&N,&K) && (N+K))
51     {
52         for(int i=0;i<N;i++)    scanf("%d",&a[i]);
53         for(int i=0;i<N;i++)    scanf("%d",&b[i]);
54         double L = 0,R = 1.0,mid;
55         while(abs(L-R) > eps)
56         {
57             mid = (L+R)/2.0;
58             for(int i=0;i<N;i++)
59                 d[i] = (double)a[i] - mid*(double)b[i];
60             if(check(mid)) L = mid;
61             else           R = mid;
62         }
63 
64         printf("%d\n",(int)(mid*100.0+0.5));
65     }    
66 }

 

posted @ 2016-03-06 11:45  Helica  阅读(233)  评论(0编辑  收藏  举报