题意:给你n个分制成绩,让你从中去掉k个分制成绩使得
这个最大
例如给定 5/5,0/1,2/6,此时平均成绩为
如果k=1 那么可获得最大的平均成绩为
思路:
研究了半天的01规划发现每个此类问题可以构造函数来操作
令∑ai/∑bi = l, 那么∑ai = l*∑bi ,令f(l) = ∑(ai - l*bi)
当∑ai / ∑bi ≥ l 时 即f(l)≥0 时说明存在更优解
通过二分即可求出最优解,
更新边界:
贪心找最大的n-k个即可,如果满足f(l)≥0,说明存在更优解l=mid;else:r=mid, (浮点数二分)
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=2e5+7;
double a[N],b[N];
int n,m;
double w[N];
int ok(double mid){
double sum=0;
for(int i=1;i<=n;i++){
//w[i]=b[i]*mid-a[i];
w[i]=a[i]-mid*b[i];
}
sort(w+1,w+1+n);
for(int i=m+1;i<=n;i++){
sum+=w[i];
}
return sum>=0;
}
int main(){
while(cin>>n>>m){
if(!n&&!m) return 0;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>b[i];
double l=0.,r=1.;
while(r-l>1e-6){
double mid=(l+r)/2.;
if(ok(mid)) l=mid;
else r=mid;
}
printf("%.lf\n",l*100.);
}
return 0;
}