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 ",(int)(ans*100+0.5)); 53 } 54 return 0; 55 }