[Niuke.com] Compras de Xiaomi (respuesta de dos puntos)

Descripción del Título:

Inserte la descripción de la imagen aquíInserte la descripción de la imagen aquíInserte la descripción de la imagen aquí

Ideas de resolución de problemas:

Supongamos que Xiaomi solo quiere comprar 3 artículos y finalmente compra los artículos i, j, ki, j, ki ,j ,k tal que el valor máximo buscado seamax maxm a x . Luego está la relaciónv [i] + v [j] + v [k] c [i] + c [j] + c [k] = max \ frac {v [i] + v [j] + v [ k]} {c [i] + c [j] + c [k]} = máx.c [ i ] + c [ j ] + c [ k ]v [ i ] + v [ j ] + v [ la k ]=m a x成立, 也 即v [i] + v [j] + v [k] - máx ∗ c [i] - máx ∗ c [j] - máx ∗ c [k] = 0 v [i] + v [j] + v [k] -max * c [i] -max * c [j] -max * c [k] = 0v [ i ]+v [ j ]+v [ k ]-m a xc [ i ]-m a xc [ j ]-m a xc [ k ]=Se establece 0 . Si solo adivinamos un númeroxxx去 替代 "v [i] + v [j] + v [k] - máx ∗ c [i] - máx ∗ c [j] - máx ∗ c [k] v [i] + v [j] + v [k] -max * c [i] -max * c [j] -max * c [k]v [ i ]+v [ j ]+v [ k ]-m a xc [ i ]-m a xc [ j ]-m a xc [ k ] "enmax maxm a x , si x se supone que es grande, entoncesv [i] + v [j] + v [k] - x [c [i] - x [c [j] - x ∗ c [k] <0 v [ i] + v [j] + v [k] -x * c [i] -x * c [j] -x * c [k] <0v [ i ]+v [ j ]+v [ k ]-Xc [ i ]-Xc [ j ]-Xc [ k ]<0 , sixxx se supone pequeño, entoncesv [i] + v [j] + v [k] - x ∗ c [i] - x ∗ c [j] - x ∗ c [k]> 0 v [i] + v [ j] + v [k] -x * c [i] -x * c [j] -x * c [k]> 0v [ i ]+v [ j ]+v [ k ]-Xc [ i ]-Xc [ j ]-Xc [ k ]>0 . A partir de esto, pensé que esta pregunta podría transformarse en una búsqueda binaria: adivine el valor máximo en el rango de respuestas posibles, adivine la más grande, adivine la más pequeña, y adivine la más pequeña y adivine la más grande. Hasta que este número se acerque almáximo máximom a x está bien.

Código AC:

#include<iostream>
#include<algorithm>
     using namespace std;
     const int maxn=1e4+100;
     int n,k;
     double c[maxn],v[maxn];
     bool check(double x){
    
    
     double y[maxn];
     for(int i=1;i<=n;i++){
    
    
      y[i]=v[i]-x*c[i];
     }
     sort(y+1,y+n+1);
     double s=0;
     for(int i=n;i>n-k;i--){
    
      //选择前k个最大y[i]累加,如果最大的累加和都小于0则这个数一定猜大了
     s+=y[i];
     }
     return s>=0;    //s>=0则表示猜小了。也即返回true时表示猜小了
     }
     int Bsearch(double l,double r){
    
    
     int t=100;      //猜100次就足以让答案满足“精确至整数”的精度。
     while(t--){
    
    
     double m=(l+r)/2;
     if(check(m)) l=m;   //猜小了就往大了猜
     else r=m;           //猜大了就往小了猜
     }
     return (int)l;
     }
     int main(){
    
    
     int t;
     cin>>t;
     while(t--){
    
    
     cin>>n>>k;
     for(int i=1;i<=n;i++){
    
    
      cin>>c[i]>>v[i];
     }
     double l=0;
     double r=1e4;      //大致估计答案在0-10000之间
     cout<<Bsearch(l,r)<<endl;
     }
    return 0;
     }


Blog anterior: [leetcode] 778. Nadar en una piscina con nivel de agua en aumento (dfs + respuesta de dos puntos)

Supongo que te gusta

Origin blog.csdn.net/IAMLSL/article/details/114242932
Recomendado
Clasificación