poj 2976 Dropping tests
01分数规划,给n个物品,选择n-k个
选出来的n-k个最大化∑A(n-k)/∑B(n-k)
即∑ai/∑bi≥x就等价于∑ai−x∑bi≥0,
之后不断的向目标推进x,一般都二分。
裸题 poj 2976 Dropping tests
1 #include <iostream> 2 #include <cstring> 3 #include <string> 4 #include <map> 5 #include <set> 6 #include <algorithm> 7 #include <fstream> 8 #include <cstdio> 9 #include <cmath> 10 #include <stack> 11 #include <queue> 12 #define mem(x) memset(x,0,sizeof(x)) 13 using namespace std; 14 typedef long long ll; 15 ll a[1000+5]; 16 ll b[1000+5]; 17 double f[1000+5]; 18 int n,k; 19 20 bool cmp(double a,double b) 21 { 22 return a>b; 23 } 24 bool C(double v) 25 { 26 double sum=0; 27 for(int i=1;i<=n;i++) 28 { 29 f[i]=a[i]-b[i]*v; 30 } 31 sort(f+1,f+n+1,cmp); 32 for(int i=1;i<=k;i++){ 33 sum+=f[i]; 34 } 35 if(sum>=0) return true; 36 else return false; 37 } 38 int main() 39 { 40 while(cin>>n>>k) 41 { 42 double ans=0; 43 if(n==0&&k==0) break; 44 for(int i=1;i<=n;i++) 45 { 46 scanf("%lld",&a[i]); 47 } 48 for(int i=1;i<=n;i++){ 49 scanf("%lld",&b[i]); 50 } 51 k=n-k; 52 double l=0,r=1; 53 while(r-l>0.000001) 54 { 55 double mid=(l+r)/2; 56 if(C(mid)) 57 { 58 59 l=mid;ans=max(ans,mid); 60 } 61 else r=mid; 62 } 63 ans=ans*100; 64 printf("%.0lf\n",ans); 65 } 66 return 0; 67 }