您的位置:首页 > 运维架构

[DP 斜率优化 CDQ分治||动态维护凸包] BZOJ 1492 [NOI2007]货币兑换Cash

2016-08-08 22:15 609 查看




打了个set维护凸包 cdq等待填坑

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<set>
#include<cmath>
#define dprintf(...) fprintf(stderr,__VA_ARGS__)
using namespace std;
//typedef long double ld;
typedef double ld;

inline void read(ld &x){
double a; scanf("%lf",&a); x=a;
}

const ld eps=1e-8;
inline int dcmp(ld a,ld b){
if (fabs(a-b)<eps) return 0;
return a<b?-1:1;
}

const int N=200005;

inline double sqr(int x){ return (double)x*x; }

struct Point{
ld x,y;
Point(ld x=0,ld y=0):x(x),y(y) { }
void print() const { dprintf("%.3lf %.3lf",x,y); }
friend bool operator < (Point A,Point B){ return dcmp(A.x,B.x)==0?dcmp(A.y,B.y)<0:dcmp(A.x,B.x)<0; }
friend ld operator * (Point A,Point B){ return A.x*B.y-A.y*B.x; }
friend Point operator - (Point A,Point B){ return Point(A.x-B.x,A.y-B.y); }
friend double dist(Point A,Point B){ return sqrt(sqr(A.x-B.x)+sqr(A.y-B.y)); }
};

struct Line{
Point p0,p1;
Line(Point a,Point b){
p0=a; p1=b;
}
bool operator < (const Line &B) const{
return dcmp((p1-p0)*(B.p1-B.p0),0)<0;
}
void print() const{
p0.print(); dprintf(" "); p1.print();
}
ld K()const{
return (p1.y-p0.y)/(p1.x-p0.x);
}
};

set<Point> Set;
set<Line> SetL;
typedef set<Point>::iterator ITER;
typedef set<Line>::iterator IT;

int clk;

inline void Ins(Point x){
ITER r=Set.lower_bound(x),l=r,t;
l--;
if(dcmp((*r-*l)*(x-*l),0)<0) return;
SetL.erase(Line(*l,*r));
Set.insert(x);
while (1)
{
t=r; r++;
if(r==Set.end()) break;
if(dcmp((*r-x)*(*t-x),0)>0) break;
SetL.erase(Line(*t,*r));
Set.erase(t);
}
while (1)
{
if (l==Set.begin()) break;
t=l; l--;
if(dcmp((*t-x)*(*l-x),0)>0) break;
SetL.erase(Line(*l,*t));
Set.erase(t);
}
Set.insert(x);
l=r=Set.find(x);
l--; r++;
SetL.insert(Line(*l,x));
SetL.insert(Line(x,*r));
// for (ITER i=Set.begin();i!=Set.end();i++) i->print(),dprintf("\n"); dprintf("\n");
// for (IT i=SetL.begin();i!=SetL.end();i++) i->print(),dprintf("\n"); dprintf("\n");
}

int n,S;
ld A
,B
,R
;
ld f
;
ld lim;

inline void Add(int i){
ld x=f[i]/(A[i]*R[i]+B[i]),y=R[i]*x;
Ins(Point(x,y));
}

int main()
{
scanf("%d%d",&n,&S);
for (int i=1;i<=n;i++)
read(A[i]),read(B[i]),read(R[i]);
Set.insert(Point(0,0));
Set.insert(Point(1e10,-1e20)); SetL.insert(Line(Point(0,0),Point(1e10,-1e20)));
f[1]=S; Add(1);
for (int i=2;i<=n;i++)
{
clk=i;
IT it=SetL.lower_bound( Line(Point(0,0),Point(A[i],-B[i])) );
Point ret=it->p0;
f[i]=max(f[i-1],B[i]*ret.x+A[i]*ret.y);
Add(i);
}
printf("%.3lf\n",(double)f
);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: