(跟之前某道题很像)
当 \(x\) 无限大时,相当于物品可以选实数个(不拘泥于整数个)。于是很自然地(也是因为价值是一维的,代价是二维的,肯定固定一维不变),把每种物品价值都变为单位 1。
于是我们得到 \(n\) 种物品,每种体积是 \(A’_i,B’_i\)。于是若选了 \(i_1,i_2,…,i_k\) 这些物品,那么最终代价就是
\[min(\lambda_1A’_{i_1}+\lambda_2A’_{i_2}+…+\lambda_kA’_{i_k}, \lambda_1B’_{i_1}+\lambda_2B’_{i_2}+…+\lambda_kB’_{i_k}), \lambda_1+\lambda_2+…+\lambda_k=1 \]
当你有足够的数学敏感度(显然我没有),那么十分容易发现(并不容易),上述表示的就是这 \(k\) 个向量 \((A’_{ik},B’_{ik})\) 构成的多边形(或直线)。
那么易得这个多边形只有下凸壳有用(因为其它点都能被它左下方的点优化)。
所以最终只需要遍历下凸壳(点+线)即可。具体操作为枚举下凸壳上相邻两点。
总时间复杂度 \(O(N\log N)\)
Notice:
memcpy(b,a,a.lenth()*sizeof(type_a));
不加 sizeof 调十年!long double 的 size 竟然高达 36!
Notice:
sort 的比较函数永远不要用 <= >= ,会 RE!!!
#include<bits/stdc++.h>
using namespace std;
#define N 200005
struct node{
long double a,b,c;
int typ;
}d[N],p[N];
bool cmp(node x,node y){
if(x.typ==y.typ){
if(x.a==y.a)return x.b>y.b;//>= <
else return x.a<y.a;
}
return x.typ<y.typ;
}
inline bool pd(node i,node j,node k){
return (j.a-i.a)*(k.b-i.b)-(j.b-i.b)*(k.a-i.a)<=0;
}
int main(){
int n;cin>>n;
for(int i=1;i<=n;++i){
cin>>d[i].a>>d[i].b>>d[i].c;
d[i].a/=d[i].c;
d[i].b/=d[i].c;
d[i].typ=0;
}
sort(d+1,d+1+n,cmp);
int tot=0;
for(int i=1;i<=n;++i){
while(tot>1&&pd(p[tot-1],p[tot],d[i]))--tot;
p[++tot]=d[i];
}
memcpy(d,p,(tot+1)*sizeof(node));//sizeof tot+1
long double ans=max(d[1].a,d[1].b);
for(int i=2;i<=tot;++i){
ans=min(ans,max(d[i].a,d[i].b));
if(fabs(d[i-1].b-d[i-1].a)<1e-5)continue;
long double p=(d[i].a-d[i].b)/(d[i-1].b-d[i-1].a);
if(p>0){//p duo jia l
ans=min(ans,(d[i].a+p*d[i-1].a)/(1+p));
}
}
ans=1.0/ans;
cout<<fixed<<setprecision(4)<<ans<<endl;
return 0;
}
原文地址:http://www.cnblogs.com/Huster-ZHY/p/16856056.html
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,请务用于商业用途!
3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员!
8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载
声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性