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

来源:互联网 发布:js把json字符串转数组 编辑:程序博客网 时间:2024/05/17 07:48
 

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;}




0 0
原创粉丝点击