题意:
有n种士兵,每个士兵有一个花费和血量和效力,你现在有b块钱买士兵,(甚至是小数个人)你得到的价值是所有士兵的血量和乘上所有士兵的效力和。问你最大价值是多少。
题解:
我没想到凸包。。然后就一直不过
可以将其转化为二维平面的问题:
首先我们将所有的花费都变为b,这样统一花费之后就是算取的比率的问题了
如果3在1,2的连线及以下,那么1,2能够组成的矩形的情况一定比1,3的大(因为他们能够组成的情况就是这条连线)。那么如果有一个点4在1,2连线的上面,那么1,2联线必定不如1,4和4,2连线。所以做出凸包,然后三分算比率即可。
#include<bits/stdc++.h>
using namespace std;
#define ld long double
const int N=3e4+5;
const double eps=1e-8;
int desc(ld a,ld b){
ld d=a-b;
if(-eps<=d&&d<=eps)
return 0;
if(d<-eps)
return -1;
return 1;
}
struct node{
ld h,w;
bool operator< (const node& a)const
{
if(desc(w,a.w)==0)
return h>a.h;
return w<a.w;
}
}p[N];
ld check2(ld r,int x,int y){
return (r*p[x].h+(1-r)*p[y].h)*(r*p[x].w+(1-r)*p[y].w);
}
ld check1(int x,int y){
ld l=0,r=1,lm,rm,ans;
while(r-l>=eps){
lm=(l*2+r)/3;
rm=(l+r*2)/3;
if(check2(lm,x,y)<check2(rm,x,y))
l=lm;
else
r=rm;
}
return check2(lm,x,y);
}
int dcmp(ld x){return fabs(x)<1e-8?0:(x>0?1:-1); }
bool In(node a,node b,node c){
node A={c.h-b.h,c.w-b.w},B={a.h-b.h,a.w-b.w};
return dcmp(B.h*A.w-A.h*B.w)>=0;
}
int main()
{
cin.tie(0);
ios::sync_with_stdio(false);
int n;
ld b,c;
cin>>n>>b;
for(int i=1;i<=n;i++){
cin>>c>>p[i].h>>p[i].w;
p[i].h=p[i].h*b/c;
p[i].w=p[i].w*b/c;
}
sort(p+1,p+1+n);
int all=0;
for(int i=1;i<=n;i++){
while(all>=2&&In(p[all-1],p[all],p[i])){
all--;
}
p[++all]=p[i];
}
ld ans=0;
for(int i=1;i<all;i++){
ans=max(ans,check1(i,i+1));
}
cout<<fixed<<setprecision(10)<<ans<<endl;
return 0;
}
/*
3 100
100 1 0.1
100 0.8 0.2
100 0.5 0.5
3 10
1 0 0
2 0 0
3 0 0
*/