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

HINT

测试数据设计使得精度误差不会超过10-7。
对于40%的测试数据,满足N ≤ 10;
对于60%的测试数据,满足N ≤ 1 000;
对于100%的测试数据,满足N ≤ 100 000;

 
 #include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const double eps=1e-;
const int maxn=;
struct Node{
double a,b,r,x,y,k;
int id;
}d[maxn],t[maxn];
double f[maxn];
int st[maxn],cnt,n;
double Abs(double a){return a>?a:-a;}
double K(int a,int b){
if(Abs(d[a].x-d[b].x)<eps)return 1e20;
return (d[a].y-d[b].y)/(d[a].x-d[b].x);
}
void Solve(int l,int r){
if(l==r){
f[l]=max(f[l],f[l-]);
d[l].y=f[l]/(d[l].r*d[l].a+d[l].b);
d[l].x=d[l].y*d[l].r;
return;
}
int mid=(l+r)>>,t1=l,t2=mid+;
for(int i=l;i<=r;i++){
if(d[i].id<=mid)
t[t1++]=d[i];
else
t[t2++]=d[i];
}
for(int i=l;i<=r;i++)d[i]=t[i];
Solve(l,mid);
cnt=;
for(int i=l;i<=mid;i++){
while(cnt>&&K(i,st[cnt])-K(st[cnt],st[cnt-])>=eps)cnt--;
st[++cnt]=i;
}
int fir=;
for(int i=mid+;i<=r;i++){
while(fir<cnt&&K(st[fir+],st[fir])-d[i].k>=eps)fir++;
f[d[i].id]=max(f[d[i].id],d[st[fir]].x*d[i].a+d[st[fir]].y*d[i].b);
}
Solve(mid+,r);
t1=l;t2=mid+;
for(int i=l;i<=r;i++){
if(t2==r+||(d[t2].x-d[t1].x>=eps||Abs(d[t2].x-d[t1].x)<eps&&d[t2].y-d[t1].y>=eps)&&t1<=mid)
t[i]=d[t1++];
else
t[i]=d[t2++];
}
for(int i=l;i<=r;i++)
d[i]=t[i];
} bool cmp(Node a,Node b){
return a.k>b.k;
}
int main(){
scanf("%d%lf",&n,&f[]);
for(int i=;i<=n;i++){
scanf("%lf%lf%lf",&d[i].a,&d[i].b,&d[i].r);
d[i].k=-d[i].a/d[i].b;
d[i].id=i;
}
sort(d+,d+n+,cmp);
Solve(,n);
printf("%.3lf\n",f[n]);
return ;
}

  这里还有Splay。

 #include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const double eps=1e-;
const double INF=1e20;
const int maxn=;
int ch[maxn][],fa[maxn],rt,tot,n;
double X[maxn],Y[maxn],lk[maxn],rk[maxn],ans;
double fabs(double x){return (x>)?x:-x;}
void Rotate(int x){
int y=fa[x],g=fa[y],c=ch[y][]==x;
ch[y][c]=ch[x][c^];fa[ch[y][c]]=y;
ch[x][c^]=y;fa[y]=x;fa[x]=g;
if(g)ch[g][ch[g][]==y]=x;
} void Splay(int x,int g=){
for(int y;(y=fa[x])!=g;Rotate(x))
if(fa[y]!=g)Rotate((ch[fa[y]][]==y)==(ch[y][]==x)?y:x);
if(!g)rt=x;
} double Get_K(int j,int k){
if(fabs(X[j]-X[k])<=eps)return INF;
else return (Y[j]-Y[k])/(X[j]-X[k]);
} int Get_Prev(){
int p=ch[rt][],ret=p;
while(p){
if(Get_K(rt,p)+eps>=lk[p])p=ch[p][];
else ret=p,p=ch[p][];
}
return ret;
} int Get_Succ(){
int p=ch[rt][],ret=p;
while(p){
if(Get_K(p,rt)<=rk[p]+eps)p=ch[p][];
else ret=p,p=ch[p][];
}
return ret;
} void Insert(int &r,int pre,int p){
if(r==){r=p;fa[p]=pre;return;}
if(X[p]<=X[r]+eps)Insert(ch[r][],r,p);
else Insert(ch[r][],r,p);
} void Update(int p){
Splay(p);
if (ch[p][]){
int l=Get_Prev();
Splay(l,p);ch[l][]=;
lk[p]=rk[l]=Get_K(p,l);
}
else lk[p]=INF;
if (ch[p][]){
int r=Get_Succ();
Splay(r,p); ch[r][]=;
rk[p]=lk[r]=Get_K(r,p);
}
else rk[p]=-INF;
if (lk[p]<=rk[p]+eps){
rt=ch[p][]; ch[rt][]=ch[p][]; fa[ch[p][]]=rt; fa[rt]=;
rk[rt]=lk[ch[p][]]=Get_K(ch[rt][],rt);
}
} int Get_Pos(double k){
int p=rt;
while(p){
if(lk[p]+eps>=k&&k+eps>=rk[p])break;
if(lk[p]<k+eps)p=ch[p][];
else p=ch[p][];
}
return p;
} double Get_Ans(double a,double b){
int p=Get_Pos(-b/a);
return a*Y[p]+b*X[p];
} int main(){
#ifndef ONLINE_JUDGE
freopen("cash.in","r",stdin);
freopen("cash.out","w",stdout);
#endif
double a,b,rate;
scanf("%d%lf",&n,&ans);
for(int i=;i<=n;i++){
scanf("%lf%lf%lf",&a,&b,&rate);
if(i!=)ans=max(ans,Get_Ans(a,b));
X[i]=ans/(rate*a+b);
Y[i]=X[i]*rate;
Insert(rt,,i);
Update(i);
}
printf("%.3f\n",ans);
return ;
}

斜率优化(CDQ分治,Splay平衡树):BZOJ 1492: [NOI2007]货币兑换Cash的更多相关文章

  1. BZOJ 1492: [NOI2007]货币兑换Cash( dp + 平衡树 )

    dp(i) = max(dp(i-1), x[j]*a[i]+y[j]*b[i]), 0<j<i. x, y表示某天拥有的最多钱去买金券, 金券a和金券b的数量. 然后就很明显了...平衡 ...

  2. bzoj 1492: [NOI2007]货币兑换Cash

    Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券(以下 简称B券).每个持有金券的顾客都有一个自己的帐户.金券的数目可以是一个 ...

  3. BZOJ.1492.[NOI2007]货币兑换(DP 斜率优化 CDQ分治/Splay)

    BZOJ 洛谷 如果某天能够赚钱,那么一定会在这天把手上的金券全卖掉.同样如果某天要买,一定会把所有钱花光. 那么令\(f_i\)表示到第\(i\)天所拥有的最多钱数(此时手上没有任何金券),可以选择 ...

  4. BZOJ 1492: [NOI2007]货币兑换Cash [CDQ分治 斜率优化DP]

    传送门 题意:不想写... 扔链接就跑 好吧我回来了 首先发现每次兑换一定是全部兑换,因为你兑换说明有利可图,是为了后面的某一天两种卷的汇率差别明显而兑换 那么一定拿全利啊,一定比多天的组合好 $f[ ...

  5. bzoj 1492 [NOI2007]货币兑换Cash(斜率dp+cdq分治)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1492   [题意] 有AB两种货币,每天可以可以付IPi元,买到A券和B券,且A:B= ...

  6. bzoj 1492: [NOI2007]货币兑换Cash【贪心+斜率优化dp+cdq】

    参考:http://www.cnblogs.com/lidaxin/p/5240220.html 虽然splay会方便很多,但是懒得写,于是写了cdq 首先要想到贪心的思路,因为如果在某天买入是能得到 ...

  7. BZOJ 1492 [NOI2007]货币兑换Cash (CDQ分治/splay 维护凸包)

    题目大意:太长了略 splay调了两天一直WA弃疗了 首先,我们可以猜一个贪心,如果买/卖,就一定都买/卖掉,否则不买/卖 反正货币的行情都是已知的,没有任何风险,所以肯定要选择最最最优的方案了 容易 ...

  8. ●BZOJ 1492 [NOI2007]货币兑换Cash

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1492 题解: 斜率优化DP,CDQ分治 定义$DP[i]$为第i天结束后的最大收益. 由于题 ...

  9. BZOJ 1492 [NOI2007]货币兑换Cash:斜率优化dp + cdq分治

    传送门 题意 初始时你有 $ s $ 元,接下来有 $ n $ 天. 在第 $ i $ 天,A券的价值为 $ A[i] $ ,B券的价值为 $ B[i] $ . 在第 $ i $ 天,你可以进行两种操 ...

随机推荐

  1. poj 3565 ants

    /* poj 3565 递归分治 还有用KM的做法 这里写的分治 按紫书上的方法 不过那里说的有点冗杂了 可以简化一下 首先为啥可以分治 也就是分成子问题解决 只要有一个集合 黑白的个数相等 就一定能 ...

  2. jquery选择器取值和url正则匹配

    用到的简单jquery知识,简单总结一下,一是能加深自己的记忆,二是方便自己以后查看.常言道"好记性不如烂笔头",要养成常总结.常记录的好习惯.慢慢的发现jquery很有意思,很强 ...

  3. NSDate和NSString的转换及判定是昨天,今天,明天

    用于uidate,picker.. +(NSDate*) convertDateFromString:(NSString*)uiDate{    NSDateFormatter *formatter ...

  4. openURL的使用方法

    openURL的使用方法 openURL的使用方法: view plaincopy to clipboardprint? [[UIApplication sharedApplication] open ...

  5. Spring 实例化bean的方式

    实例化bean的方式有三种: 1.用构造器来实例化 2.使用静态工厂方法实例化 3.使用实例工厂方法实例化 当采用构造器来创建bean实例时,Spring对class并没有特殊的要求, 我们通常使用的 ...

  6. WebService开发步骤

    WebService原理什么的百度很多我就说了,无非就是提供一个接口放在服务端,客户端实现这个接口就可以拿到自己需要的东西. 现在简单说一下用myEclipse来实现服务端和客户端.另一种WebSer ...

  7. POJ刷题记录 (。・`ω´・)(Progress:6/50)

    1743:前后作差可以转化成不可重叠最长公共字串问题,运用后缀数组解决(参考罗穗骞神犇的论文) #include <cstdio> #include <cstring> #in ...

  8. U盘美化(更换U盘logo和页面背景软件)

    U盘内新建txt文本后,输入 [autorun] ICON=ooopic_1459309050.ico 保存的文件名包括后缀更改为autorun.inf 必须为icon图标

  9. Sql Server 时间格式

    问题引出: Sql Server 里 dateTime 数据类型,会精确到毫秒.如果我们 在插入一条数据的时候,使用 GetDate() 记录 这个记录插入的时间,则会插入当前时间,精确到毫秒.在查询 ...

  10. java 下载文件 内容为空。

    检查下是不是io流没有关闭,记得关闭所有流.