Significado de la pregunta: le otorga n puntajes basados en puntos y le pide que les elimine k puntajes basados en puntos para lograr
este máximo
. Por ejemplo, dado 5/5, 0/1, 2/6, el puntaje promedio en este momento es Si
k=1, entonces puedes obtener El puntaje promedio máximo es
Idea:
Después de estudiar la planificación 01 durante medio día, descubrí que cada uno de estos problemas se puede solucionar construyendo una función:
sea ∑ai/∑bi = l, luego ∑ai = l*∑bi, sea f(l) = ∑(ai - l*bi )
Cuando ∑ai / ∑bi ≥ l, es decir, cuando f(l)≥0, significa que hay una mejor solución.
La solución óptima se puede encontrar mediante bisección,
Actualice el límite:
simplemente encuentre el nk más grande con avidez. Si se satisface f (l) ≥ 0, significa que hay una mejor solución l = mid; de lo contrario: r = mid, (número de punto flotante dividido en dos)
#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;
}