您的位置:首页 > 其它

bzoj [NOI2007]货币兑换Cash (cdq分治+斜率优化 )

2015-08-04 19:59 543 查看

1492: [NOI2007]货币兑换Cash

Time Limit: 5 Sec Memory Limit: 64 MB

Submit: 2454 Solved: 1078

[Submit][Status][Discuss]

Description



Input

第一行两个正整数N、S,分别表示小Y 能预知的天数以及初始时拥有的钱数。 接下来N 行,第K 行三个实数AK、BK、RateK,意义如题目中所述

Output

只有一个实数MaxProfit,表示第N 天的操作结束时能够获得的最大的金钱 数目。答案保留3 位小数。

Sample Input

3 100

1 1 1

1 2 2

2 2 3

Sample Output

225.000

按照cdq论文上的说法,应该写成n*lgn 。然而我强行每次都扫描凸包,复杂度多了多个一个lgn T_T。

#include<cstdio>
#include<cmath>
#include<queue>
#include<stack>
#include<string>
#include<cstring>
#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
#include<stdlib.h>
#include<set>
#include<ctime>
#include<cmath>
#include<iomanip>
using namespace std;
typedef long long LL;
const int mmax  = 100010;
const int inf = 0x3fffffff;
const double eps = 1e-8;
double A[mmax],B[mmax],R[mmax];
double f[mmax];
double dp[mmax];

int sgn(double x)// ·ûºÅº¯Êý
{
if(fabs(x)<eps)
return 0;
return x<0?-1:1;
}

struct Point
{
double x,y;
Point(double x=0.0,double y=0.0):x(x),y(y) {}
void read()
{
scanf("%lf %lf",&x,&y);
}
};
typedef Point Vector;
Vector operator + (Vector A,Vector B)
{
return Vector(A.x+B.x,A.y+B.y);
}

Vector operator - (Point A,Point B)
{
return Vector(A.x-B.x,A.y-B.y);
}
Vector operator * (Vector A,double p)
{
return Vector(A.x*p,A.y*p);
}
Vector operator / (Vector A,double p)
{
return Vector(A.x/p,A.y/p);
}

bool operator < (const Point &a,const Point &b)
{
return a.x<b.x || (a.x==b.x&&a.y<b.y);
}
//ÔËË㲿·Ö
double Dot(Vector A,Vector B)
{
return A.x*B.x+A.y*B.y;
}
double Cross(Vector A,Vector B)
{
return A.x*B.y-A.y*B.x;
}

double x(int i)
{
return dp[i]*R[i]/f[i];
}
double y(int i)
{
return dp[i]/f[i];
}

bool cmp(int i,int j)
{
return A[i]*B[j]>A[j]*B[i];
}

int ConvexHull(Point *p,int n,Point *Poly)
{
sort(p,p+n);
int m=0;
for(int i=n-1;i>=0;i--)
{
while(m>1 && Cross(Poly[m-1]-Poly[m-2],p[i]-Poly[m-2]) <=0 ) m--;
Poly[m++]=p[i];
}
return m;
}
Point P[mmax],Poly[mmax];
int tmp[mmax];
void cdq(int l,int r)
{
if(l==r)
{
dp[l]=max(dp[l],dp[l-1]);
return ;
}

int mid=(l+r)>>1;
cdq(l,mid);
int cnt=0;
for(int i=l;i<=mid;i++)
P[cnt++]=Point(x(i),y(i));

cnt=ConvexHull(P,cnt,Poly);
for(int i=mid+1;i<=r;i++)
tmp[i]=i;
sort(tmp+mid+1,tmp+r+1,cmp);

int i=0,j=mid+1;

while(j<=r)
{
while(i<cnt-1 && (Poly[i].y-Poly[i+1].y )*B[tmp[j]] < -1.0*(Poly[i].x-Poly[i+1].x)*A[tmp[j]]  )
i++;
dp[tmp[j]]=max(dp[tmp[j]],A[tmp[j]]*Poly[i].x+B[tmp[j]]*Poly[i].y);
j++;
}
cdq(mid+1,r);

}
int main()
{

int n,s;
cin>>n>>s;
for(int i=1;i<=n;i++)
{
scanf("%lf %lf %lf",&A[i],&B[i],&R[i]);
f[i]=A[i]*R[i]+B[i];
}
memset(dp,0,sizeof dp);
dp[0]=1.0*s;
cdq(1,n);

double ans=0;
for(int i=1;i<=n;i++)
ans=max(ans,dp[i]);
printf("%.3lf\n",ans);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: