题目大意:太长了略

splay调了两天一直WA弃疗了

首先,我们可以猜一个贪心,如果买/卖,就一定都买/卖掉,否则不买/卖

反正货币的行情都是已知的,没有任何风险,所以肯定要选择最最最优的方案了

容易得到方程

$dp[i]=max(dp[i-1],a[i]*\frac{dp[j]*rate[j]}{rate[j]*a[j]+b[j]}+b[i]*\frac{dp[j]}{rate[j]*a[j]+b[j]})$

显然是要用凸优化了

splay非常无脑,splay维护此题的凸包,需要找前驱,删前驱,找后继,删后继,一大堆特判...绝对恶心到吐

所以这是一篇$CDQ$分治题解

令$x=\frac{dp[j]}{rate[j]*a[j]+b[j]},y=x*rate[j]$

移项,可得

$dp[i]-b[i]*x=a[i]*y$

$y=\frac{dp[i]}{a[i]}-\frac{b[i]}{a[i]}x$

发现斜率$k=-\frac{b[i]}{a[i]}$是一定的,我们在外层把斜率k从小到大排序,可以优化掉一个$log$,递归时按$x$从小到大排序

这样,递归时,每一层内部都是按$k$有序的,把这一层按照时间分为左右两个部分(不要破坏$k$的有序状态)

先递归处理左半个区间,回溯后,左半部分的答案已知,且不会被右半部分的答案所影响

且左半部分按$x$从小到大排序,右半部分按斜率$k$从小到大排序,取最小值,由于$k<0$,用单调栈维护一个上凸包即可

处理完了左边对右边的贡献,递归处理右半部分

回溯时,先处理$dp[i]=dp[i-1]$的情况,再按$x$排序,回溯到上一层

 #include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N1 101000
#define M1 205
#define ll long long
#define dd double
#define uint unsigned int
#define inf 233333333
#define il inline
using namespace std; const dd eps=(1e-);
int n,m;
int stk[N1];
dd A[N1],B[N1],r[N1],X[N1],Y[N1],K[N1],f[N1];
//struct node{dd x,y,k,ans;int id;};
int cmp1(int s1,int s2){return K[s1]-K[s2]<;}
int id[N1],tmp[N1];
dd get_slope(int s1,int s2){
if(!s2) return inf;
return (Y[s1]-Y[s2])/(X[s1]-X[s2]);
}
void CDQ(int L,int R)
{
if(R-L<=) return;
int M=(L+R)>>;
int tp=,i,j,pl=L,pr=M,k,cnt;
for(int i=L;i<R;i++)
if(id[i]<M) tmp[pl++]=id[i];
else tmp[pr++]=id[i];
for(int i=L;i<R;i++)
id[i]=tmp[i];
CDQ(L,M);
for(i=L;i<M;i++)
{
k=id[i];
if(tp>&&fabs(X[stk[tp]]-X[k])<eps&&Y[k]-Y[stk[tp]]<eps) continue;
while(tp>&&get_slope(stk[tp],stk[tp-])<=get_slope(k,stk[tp-]))
tp--;
stk[++tp]=k;
}
for(i=M;i<R;i++)
f[i]=max(f[i-],f[i]);
for(i=M;i<R;i++)
{
while(tp>&&get_slope(stk[tp],stk[tp-])<=K[id[i]])
tp--;
k=id[i],j=stk[tp];
f[k]=max(f[k],A[k]*Y[j]+B[k]*X[j]);
X[k]=f[k]/(A[k]*r[k]+B[k]);
Y[k]=r[k]*X[k];
}
CDQ(M,R);
i=L,cnt=L,j=M;
while(i<M&&j<R){
if(X[id[i]]<X[id[j]])
tmp[cnt++]=id[i],i++;
else
tmp[cnt++]=id[j],j++;
}
while(i<M) tmp[cnt++]=id[i],i++;
while(j<R) tmp[cnt++]=id[j],j++;
for(i=L;i<R;i++)
id[i]=tmp[i],f[id[i]]=max(f[id[i]],f[id[i]-]);
};
dd S;
int main()
{
//freopen("t1.in","r",stdin);
scanf("%d%lf",&n,&S);
for(int i=;i<=n;i++)
{
scanf("%lf%lf%lf",&A[i],&B[i],&r[i]);
K[i]=-B[i]/A[i];id[i]=i;
}
f[]=S,X[]=S/(A[]*r[]+B[]),Y[]=X[]*r[];
sort(id+,id+n+,cmp1);
CDQ(,n+);
dd ans=;
for(int i=;i<=n;i++)
ans=max(ans,f[i]);
printf("%.3lf\n",ans);
return ;
}

BZOJ 1492 [NOI2007]货币兑换Cash (CDQ分治/splay 维护凸包)的更多相关文章

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

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

  2. BZOJ 1492: [NOI2007]货币兑换Cash 斜率优化 + splay动态维护凸包

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

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

    [BZOJ1492] [NOI2007] 货币兑换Cash(cdq分治+斜率优化) 题面 分析 dp方程推导 显然,必然存在一种最优的买卖方案满足:每次买进操作使用完所有的人民币:每次卖出操作卖出所有 ...

  4. bzoj1492[NOI2007]货币兑换Cash cdq分治+斜率优化dp

    1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 5541  Solved: 2228[Submit][Sta ...

  5. 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的数量. 然后就很明显了...平衡 ...

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

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

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

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

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

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

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

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

随机推荐

  1. JavaScript模块化编程之AMD

    简单的说一下AMD是"Asynchronous Module Definition"的缩写,意思就是"异步模块定义".它采用异步方式加载模块,模块的加载不影响它 ...

  2. Linux设备驱动--块设备(二)之相关结构体(转)

    上回最后面介绍了相关数据结构,下面再详细介绍 块设备对象结构 block_device 内核用结构block_device实例代表一个块设备对象,如:整个硬盘或特定分区.如果该结构代表一个分区,则其成 ...

  3. Problem 14

    Problem 14 # Problem_14.py """ The following iterative sequence is defined for the se ...

  4. PHP开发实战权威指南-读书总结

    从今年开始,断断续续学习PHP已经有4个月了.最初,认真学习PHP几天,就弄WordPress搭建了一个个人博客,这也符合技术人的实践理念. 最近,重温PHP开发实战权威指南,做点总结,整理下自己学习 ...

  5. yii AR 模式操作

    Bat::find() ; //返回查询实例 Bat::find()->one() //返回一条数据 Bat::find()->all(); //返回所有数据 Bat::find()-&g ...

  6. [SharePoint2010开发入门经典]9创建更好的用户体验----silverlight

    本章概要: 1.了解Silverlight 2.理解为什么使用Silverlight 3.介绍如何集成SharePoint和Silverlight

  7. Java设计模式透析之 —— 模板方法(Template Method)

    今天你还是像往常一样来上班,一如既往地開始了你的编程工作. 项目经理告诉你,今天想在server端添加一个新功能.希望写一个方法.能对Book对象进行处理.将Book对象的全部字段以XML格式进行包装 ...

  8. 51nod-1462: 树据结构

    [传送门:51nod-1462] 简要题意: 给出一棵n个点的树,每个点有两个权值v,t 有Q个操作,有两种操作: 1.将x到根上的路径上的点的v值都加上d 2.将x到根上的路径上的点的t值都加上每个 ...

  9. dnscapy使用——本质上是建立ssh的代理(通过dns tunnel)

    git clone https://github.com/cr0hn/dnscapy.git easy_install Scapy 服务端: python dnscapy_server.py a.fr ...

  10. 使用右键打开Visual Code

    Windows Registry Editor Version 5.00[HKEY_CLASSES_ROOT\*\shell\Visual Code]@="Edit with Visual ...