传送门

首先有一个显然的贪心,每次操作都要做到底,为了最优不会出现只卖一部分或者只买一部分的操作

所以设 $f[i]$ 表示前 $i$ 天得到的最大价值,那么对于每一个 $i$,枚举所有 $j<i$,意思就是第 $j$ 天全部买入,第 $i$ 天全部卖出

显然如果知道 $f[j]$,那么就知道第 $j$  天买入多少

设 $A$ 买了 $X$, $B$ 买了 $Y$,那么 $f[i]=a[i]*X+b[i]*Y$

因为 $X,Y$ 只和 $j$ 有关,显然可以斜率优化

具体就是 $-a[i]*X+f[i]=b[i]*Y$,同除一个 $b[i]$,变成 $-a[i]/b[i]*X+f[i]/b[i]=Y$
那么 $k=-a[i]/b[i],x=X,b=f[i]/b[i],y=Y$

自己推一下,容易得出 $X_i=f[i]*r[i]/(a[i]*r[i]+b[i]),Y_i=f[i]/(a[i]*r[i]+b[i])$

然后因为 $k,x$ 都不单调,所以要用 $CDQ$ 搞

先按斜率排序,然后 $CQD$ 分治之前按下标拆成两部分,这个具体还是看代码吧...

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;
typedef double db;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=2e5+,INF=1e9+;
const db eps=1e-;
int n,S;
db f[N];
struct dat{
db k,x,y,a,b,r;
int id;
inline bool operator < (const dat &tmp) const {
return k<tmp.k;
}
}T[N],tmp[N];
inline db slope(int i,int j)//求斜率维护凸包
{
if(fabs(T[i].x-T[j].x)<=eps) return T[i].y>T[j].y ? INF : -INF;
return (T[i].y-T[j].y)/(T[i].x-T[j].x);
}
inline db Cross(db xa,db ya,db xb,db yb) { return xa*yb-xb*ya; }//用叉积维护凸包会更快
inline void merge(int l,int r,int mid)//按x归并排序
{
int pl=l,pr=mid+;
for(int p=l;p<=r;p++)
{
if(pl<=mid&& (pr>r||T[pl].x<T[pr].x/*+eps*/) ) tmp[p]=T[pl++];
else tmp[p]=T[pr++];
}
for(int p=l;p<=r;p++) T[p]=tmp[p];
}
int Q[N];//栈,维护凸包
void CDQ(int l,int r)
{
if(l==r)//到了最底下,此时f[l]已经被所有f[j](j<l)更新完毕
{
f[l]=max(f[l],f[l-]);//这一天可以不操作
T[l].y=f[l]/(T[l].a*T[l].r+T[l].b),T[l].x=T[l].y*T[l].r;
//更新f[l]完才求X[l],Y[l]
return;
}
int mid=l+r>>,pl=l,pr=mid+,top=;
for(int p=l;p<=r;p++)//按下标分开
{
if(T[p].id<=mid) tmp[pl++]=T[p];
else tmp[pr++]=T[p];
}
for(int p=l;p<=r;p++) T[p]=tmp[p];
CDQ(l,mid); Q[]=;//先处理左边
for(int i=l;i<=mid;i++)//此时左边全部更新完毕,可以维护左边构成的凸包了
//注意此时左边的T[i].x是有序的,因为每次CDQ结束都会merge
{
while( top> &&
Cross(T[i].x-T[Q[top-]].x,T[i].y-T[Q[top-]].y,T[Q[top]].x-T[Q[top-]].x,T[Q[top]].y-T[Q[top-]].y)<= ) top--;
Q[++top]=i;
}
for(int i=mid+;i<=r;i++)//用左边构成的凸包更新右边,此时右边的斜率是有序的
{
while( top> && /*T[i].k>=slope(Q[top-1],Q[top])+eps*/ //注释的内容和下一行是等价的,注意eps
Cross(,T[i].k,T[Q[top]].x-T[Q[top-]].x,T[Q[top]].y-T[Q[top-]].y)<= ) top--;
int j=Q[top]; f[T[i].id]=max(f[T[i].id],T[j].x*T[i].a+T[j].y*T[i].b);//更新
}
CDQ(mid+,r); merge(l,r,mid);//处理右边后按x排序
}
int main()
{
n=read(); f[]=read();
for(int i=;i<=n;i++)
{
scanf("%lf%lf%lf",&T[i].a,&T[i].b,&T[i].r);
T[i].k=-T[i].a/T[i].b; T[i].id=i;//初始化
}
sort(T+,T+n+); CDQ(,n);//先按k排序再CDQ
printf("%.3lf",f[n]);
return ;
}

P4027 [NOI2007]货币兑换的更多相关文章

  1. P4027 [NOI2007]货币兑换(斜率优化dp+cdq分治)

    P4027 [NOI2007]货币兑换 显然,如果某一天要买券,一定是把钱全部花掉.否则不是最优(攒着干啥) 我们设$f[j]$为第$j$天时用户手上最多有多少钱 设$w$为花完钱买到的$B$券数 $ ...

  2. 洛谷 P4027 [NOI2007]货币兑换 解题报告

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

  3. 洛谷P4027 [NOI2007]货币兑换

    P4027 [NOI2007]货币兑换 算法:dp+斜率优化 题面十分冗长,题意大概是有一种金券每天价值会有变化,你可以在某些时间点买入或卖出所有的金券,问最大收益 根据题意,很容易列出朴素的状态转移 ...

  4. LOJ 2353 & 洛谷 P4027 [NOI2007]货币兑换(CDQ 分治维护斜率优化)

    题目传送门 纪念一下第一道(?)自己 yy 出来的 NOI 题. 考虑 dp,\(dp[i]\) 表示到第 \(i\) 天最多有多少钱. 那么有 \(dp[i]=\max\{\max\limits_{ ...

  5. 洛谷P4027 [NOI2007]货币兑换(dp 斜率优化 cdq 二分)

    题意 题目链接 Sol 解题的关键是看到题目里的提示... 设\(f[i]\)表示到第\(i\)天所持有软妹币的最大数量,显然答案为\(max_{i = 1}^n f[i]\) 转移为\(f_i = ...

  6. LUOGU P4027 [NOI2007]货币兑换 (斜率优化+CDQ分治)

    传送门 解题思路 题目里有两句提示一定要看清楚,要不全买要不全卖,所以dp方程就比较好列,f[i]=max(f[j]*rate[j]*a[i])/(rate[j]*a[j]+b[j])+(f[j]*b ...

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

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

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

  9. cdq分治(hdu 5618 Jam's problem again[陌上花开]、CQOI 2011 动态逆序对、hdu 4742 Pinball Game、hdu 4456 Crowd、[HEOI2016/TJOI2016]序列、[NOI2007]货币兑换 )

    hdu 5618 Jam's problem again #include <bits/stdc++.h> #define MAXN 100010 using namespace std; ...

随机推荐

  1. CENTOS7 YUM安装BOOST1.53(静态版本)

    按照之前的博文更新163的源之后,执行: yum install boost-static.i686 yum install boost-devel.i686 yum install boost-do ...

  2. 查看ubuntu 14.04的网关和DNS

    root@ubuntu:~# nm-tool NetworkManager Tool State: connected (global) - Device: eth0 [自动以太网] -------- ...

  3. git hook 自动部署

    1. 当前虚拟站点根目录的 .git/ 权限 2. 当前项目裸仓库创建 hooks/post-receive 文件,并给予x 的权限 3. 复制如下内容 #!/bin/sh unset $(git r ...

  4. kcp源码走读

    kcp协议与tcp协议类似,是一种ARQ协议.他的优点在于比tcp的延迟更小30%-40%,但相应的会牺牲一部分的带宽,大该比tcp多浪费10%~20%.tcp的设计目标是增大网络利用率,而kcp的设 ...

  5. 大前端涉猎之前后端交互总结1: 软件架构与PHP搭建

    1 软件架构与PHP搭建 1.1 HTTP服务器(web服务器) 即( web服务器 )网站服务器,主要提供文档(文本.图片.视频.音频)web浏览服务,一般安装Apache.Nginx服务器软件. ...

  6. ORB_SLAM2_Android

    链接:https://github.com/FangGet/ORB_SLAM2_Android README.md 说明文件 This Project is out of date 该工程过时了 Th ...

  7. post上传文件限制--另一种解决途径

    问题:项目之前的上传功能是没有问题的,但是今天同样的代码上传一个压缩包的时候出现了问题,报的是struts.xml的错,说是找不到返回的映射, 问题截图: 很奇怪的问题,之前都没问题的,仔细对比后发现 ...

  8. spring事务以及springweb

    什么是事务.事务特性.事务隔离级别.spring事务传播特性 https://www.cnblogs.com/zhangqian1031/p/6542037.html Spring AOP 中@Poi ...

  9. 【微服务架构】SpringCloud之Hystrix断路器(六)

    一:什么是Hystrix 在分布式环境中,许多服务依赖项中的一些将不可避免地失败.Hystrix是一个库,通过添加延迟容差和容错逻辑来帮助您控制这些分布式服务之间的交互.Hystrix通过隔离服务之间 ...

  10. Linq的使用场景简介和认识

    一:C#的一个分支Linq 二:学Linq需要有一些基础知识 1. var 隐式类型 2. 匿名类型/匿名方法 3. 自动属性 4. 委托/泛型的委托 5. lambda 6. 扩展方法 7. 对象初 ...