[Niuke.com] Shopping Xiaomi (réponse en deux points)

Description du titre:

Insérez la description de l'image iciInsérez la description de l'image iciInsérez la description de l'image ici

Idées de résolution de problèmes:

Supposons que Xiaomi veuille seulement acheter 3 articles et achète enfin les articles i, j, ki, j, kmoi ,j ,k tel que la valeur maximale recherchée soitmax maxm un x . Alors il y a la relationv [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]} = maxc [ i ] + c [ j ] + c [ k ]v [ i ] + v [ j ] + v [ le k ]=m a x成立, 也 即v [i] + v [j] + v [k] - max ∗ c [i] - max ∗ c [j] - max ∗ 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 un xc [ i ]-m un xc[j]-m un xc [ k ]=0 est établi. Si nous devinons juste un nombrexxx去 替代 "v [i] + v [j] + v [k] - max ∗ c [i] - max ∗ c [j] - max ∗ c [k] v [i] + v [j] + v [k] -max * c [i] -max * c [j] -max * c [k]v [ i ]+v [ j ]+v [ k ]-m un xc [ i ]-m un xc[j]-m un xc [ k ] "dansmax maxm a x , si x est supposé grand, alorsv [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 est supposé petit, alorsv [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 . À partir de là, j'ai pensé que cette question pouvait être transformée en une recherche binaire: devinez la valeur maximale dans la gamme de réponses possibles, devinez la plus grande, devinez la plus petite, devinez la plus petite et devinez la plus grande. Jusqu'à ce que ce nombre soit proche demax maxm un x est bien.

Code 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 précédent: [leetcode] 778. Nager dans une piscine avec montée d'eau (dfs + réponse à deux points)

Je suppose que tu aimes

Origine blog.csdn.net/IAMLSL/article/details/114242932
conseillé
Classement