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 }