传送门

考虑令f[i]f[i]f[i]为第iii天得到的最多的AAA券,g[i]g[i]g[i]为第iii天得到的最多的BBB券
则g[i]=f[i]/rate[i]g[i]=f[i]/rate[i]g[i]=f[i]/rate[i]

那显然有个n2dpn^2dpn2dp,暴力枚举前一天转移
但显然这样得不到满分

考虑如果前面i,ji,ji,j两天对于决策nownownow的影响,如果iii比jjj优的话
则(f[i]−f[j])∗a[now]−(g[i]−g[j])∗b[now]>0(f[i]-f[j])*a[now]-(g[i]-g[j])*b[now]>0(f[i]−f[j])∗a[now]−(g[i]−g[j])∗b[now]>0

即g[i]−g[j]f[i]−f[j]&lt;−a[now]b[now]\frac{g[i]-g[j]}{f[i]-f[j]}&lt;-\frac{a[now]}{b[now]}f[i]−f[j]g[i]−g[j]​<−b[now]a[now]​

注意特判一个f[i]=f[j]f[i]=f[j]f[i]=f[j]的情况

如果将(f[i],g[i])(f[i],g[i])(f[i],g[i])作为平面上的点,那也就是我们维护一个上凸壳

则对于每一个nownownow,我们找到最后一个满足相邻2点斜率小于−a[now]b[now]-\frac{a[now]}{b[now]}−b[now]a[now]​的点,并把这个点更新当前节点的答案

但我们发现这个无法二分求
考虑splay动态维护 cdqcdqcdq分治维护凸包

具体的我们可以使nownownow保持有序
就可以一边扫凸包一边更新了

可以大力sortsortsort,不过要多一个logloglog
也可以cdqcdqcdq分治中途把凸包和−a[now]b[now]-\frac{a[now]}{b[now]}−b[now]a[now]​顺带归并排序

复杂度O(nlogn)O(nlogn)O(nlogn),似乎不比每次sortsortsort快多少……

#include<bits/stdc++.h>
using namespace std;
inline int read(){char ch=getchar();int res=0,f=1;while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=getchar();return res*f;
}
#define db double
const double eps=1e-8;
#define inf 0x7fffffff
const int N=100005;
int n,top,stk[N],id[N],tmp[N],idx[N],tmpk[N],bel[N];
db ans[N],f[N],g[N],ak[N],bk[N],rate[N];
inline db max(db a,db b){return a>b?a:b;}
inline int check(db k){return (k>-eps)-(k<eps);
}
inline bool comp(int a,int b){return f[a]<f[b]||(check(f[a]-f[b])==0&&g[a]<g[b]);
}
inline double k(int a,int b){if(check(f[a]-f[b])==0)return check(g[a]-g[b])*inf;return ((g[a]-g[b])/(f[a]-f[b]));
}
inline bool compk(int a,int b){return check((-ak[a]/bk[a])-(-ak[b]/bk[b]))>0;
}
void cdq(int l,int r){if(l==r){g[l]=f[l]/rate[l];return;}int mid=(l+r)>>1,cnt1=l-1,cnt2=mid,cnt=l-1;for(int i=l;i<=r;i++)if(bel[idx[i]]<=mid)tmpk[++cnt1]=idx[i];else tmpk[++cnt2]=idx[i];for(int i=l;i<=r;i++)idx[i]=tmpk[i];cdq(l,mid);top=0;for(int i=l;i<=mid;i++){while(top>=2&&k(stk[top-1],stk[top])<k(stk[top],id[i]))top--;stk[++top]=id[i];}for(int now=1,i=mid+1;i<=r;i++){int t=bel[idx[i]];while(now<top&&check(k(stk[now],stk[now+1])-(-ak[t]/bk[t]))>=0)now++;ans[t]=max(ans[t],f[stk[now]]*ak[t]+g[stk[now]]*bk[t]);}for(int i=mid+1;i<=r;i++){int t=bel[idx[i]];ans[t]=max(ans[t],ans[t-1]),f[t]=ans[t]*rate[t]/(ak[t]*rate[t]+bk[t]);}   cdq(mid+1,r);cnt1=l,cnt2=mid+1,cnt=l;while(cnt1<=mid&&cnt2<=r)if(comp(id[cnt1],id[cnt2]))tmp[cnt++]=id[cnt1++];else tmp[cnt++]=id[cnt2++];while(cnt1<=mid)tmp[cnt++]=id[cnt1++];while(cnt2<=r)tmp[cnt++]=id[cnt2++];for(int i=l;i<=r;++i)id[i]=tmp[i];
}
int main(){n=read();scanf("%lf",&ans[1]);for(int i=1;i<=n;i++)scanf("%lf%lf%lf",&ak[i],&bk[i],&rate[i]);f[1]=ans[1]*rate[1]/(ak[1]*rate[1]+bk[1]);for(int i=1;i<=n;i++)id[i]=idx[i]=bel[i]=i;sort(bel+1,bel+n+1,compk);cdq(1,n);printf("%.3lf",ans[n]);
}

转载于:https://www.cnblogs.com/stargazer-cyk/p/11145625.html

【BZOJ1492】【NOI2007】—Cash(cdq分治维护凸包优化斜率dp)相关推荐

  1. NOI2007 货币兑换 - CDQ分治斜率优化dp

    斜率优化dp维护一个凸壳.如果\(x, y\)坐标都递增,可以用单调队列,如果只有\(x\)递增,可以在凸壳上二分斜率,如果\(x, y\)都不递增,则需要在凸包中插入,可以用平衡树或cdq分治维护. ...

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

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

  3. bzoj2961 共点圆 (CDQ分治, 凸包)

    /* 可以发现可行的圆心相对于我们要查询的点是在一个半平面上, 然后我们要做的就是动态维护凸壳然后用这个半平面去切它 看看是否是在合法的那一面然后cdq分治就可以了代码基本是抄的,*/#include ...

  4. [BZOJ1492] [NOI2007]货币兑换Cash 斜率优化+cdq/平衡树维护凸包

    1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 5907  Solved: 2377 [Submit][S ...

  5. BZOJ1492: [NOI2007]货币兑换Cash(CDQ分治,斜率优化动态规划)

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

  6. bzoj1492 货币兑换cash dp斜率优化+splay/cdq分治

    斜率优化 首先,由于如果在i天买在j天卖有利可图,那么最优方法就是在i天花完钱在j天卖完.我们令 f i f_i fi​为第i天可以得到的最多钱数,然后可以先列方程求出花完钱在第j天得到的两种金券数 ...

  7. bzoj千题计划237:bzoj1492: [NOI2007]货币兑换Cash

    http://www.lydsy.com/JudgeOnline/problem.php?id=1492 dp[i] 表示 第i天卖完的最大收益 朴素的dp: 枚举从哪一天买来的在第i天卖掉,或者是不 ...

  8. 【BZOJ1492】[NOI2007]货币兑换Cash 斜率优化+cdq分治

    [BZOJ10492][NOI2007]货币兑换Cash Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券(以下简称B券).每 ...

  9. bzoj1492 [NOI2007]货币兑换Cash (斜率DP+cdq分治)

    题意:到处都找得到. 我没看错的话当年考试的时候的题面里头,是提示了买卖一定是全部买入和卖出的.这样一来就好办了.cdq的论文里面那个F并不是她所说的那样,而是就是那个最优值.方程转移的时候实际上是枚 ...

最新文章

  1. 上班第一天公司要你用Spring Boot 实现万能文件在线预览
  2. EasyUI--datebox设置默认时间
  3. ServletContext 与application的异同
  4. 现在没点硬核技术都不敢卖货了
  5. mongodb 查看数据库和空间大小
  6. springboot的war和jar包
  7. uint32_t 是常数吗_UINT_MAX常数,带C ++示例
  8. 《学习之道》第六章习惯的部分-反应程序
  9. linux内核实现片选跳变,《Linux内核设计与实现》读书笔记:进程调度
  10. 目标检测数据集PASCAL VOC详解
  11. 最专业逻辑图和最专业项目文档制作实战讲解
  12. IPCam的启动过程和工作流程
  13. 阿里云云计算工程师ACA认证(Alibaba Cloud Certified Associate - Cloud Computing)考试大纲-V3.0
  14. 腾讯云神笔低代码平台的申请没通过,只能等公测了
  15. 使用ale-import-roms导入atari的rom时RuntimeError问题解决办法
  16. oppo手机在哪看电池寿命
  17. python解锁电脑屏幕_使用Python解锁计算机屏幕
  18. Matlab:多项式的四则运算
  19. 科技项目申报的几个技巧
  20. 期末项目——同源药膳堂

热门文章

  1. mysql144错误_MySQL 144错误
  2. 浅谈移动LSTP的建设
  3. php(TP5)图片无损压缩上传到七牛云
  4. Android开发:Android颜色透明度换算表
  5. 宗海图cad_AutoCAD技术在海域使用论证宗海图绘制中的应用
  6. iOS 图标尺寸及用途。
  7. 相应的游戏服务器组件信息不存在,房间创建失败
  8. Ngrok服务器+客户端搭建教程
  9. 华为机试 经验(血泪史啊)
  10. 优化版本的Json Viewer工具