设f[i]是第i天能获得的最大钱数,那么
f[i]=max{在第j天用f[j]的钱买,然后在第i天卖得到的钱,f[i-1]}
然后解一解方程什么的,设$x[j]=\frac{F[j]}{A[j]*Rate[j]+B[j]}$,$y[j]=Rate[j]*x[j]$的话,就能得到$f[i]=max\{y[j]*A[i]+x[j]*B[i],f[i-1]\}$
然后再推一波斜率优化的式子,就可以得到,当j1比j2优时,$\frac{y[j1]-y[j2]}{x[j1]-x[j2]}<-\frac{B[i]}{A[i]}$
然而$-\frac{B[i]}{A[i]}$这玩意并不单调,所以需要用splay或者cdq分治维护一个斜率递减的凸包,来查询满足上式的斜率最大的那个点。
然而懒得写splay了,所以用cdq分治来做(wa了几发以后才发现还不如去写splay呢写splay就不只是wa了)
我们来分治对所有点的询问。当然需要按照i从小到大来做。
然后在做一个区间的时候,我是想用它的左子区间(保证这些的值已经求完了)去更新右子区间的值。
也就是说,需要先做左子区间,然后做当前区间,最后再做右子区间(原理和寻找宝藏是一样的)
做的时候,左边按x值排序,右边按$-\frac{B[i]}{A[i]}$排序,然后给左半边用栈维护一个凸包,再用右半边的去扫,更新结果就行了。
(别忘了f[i]可以等于f[i-1],具体做法是在l=r的时候更新一下)
(常数好像写得很大..不管了.....)
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<set>
#include<ctime>
#define LL long long
using namespace std;
const int maxn=; LL rd(){
LL x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} int N,stk[maxn],arr[maxn],tmp[maxn];
double f[maxn],A[maxn],B[maxn],R[maxn]; inline double gety(int i){return R[i]*f[i]/(A[i]*R[i]+B[i]);}
inline double getx(int i){return f[i]/(A[i]*R[i]+B[i]);}
inline double gett(int i){return -B[i]/A[i];}
inline double getk(int i,int j){
double dx=getx(i)-getx(j);if(fabs(dx)<=1e-) dx=1e-;
return (gety(i)-gety(j))/dx;
}
inline bool cmpl(int a,int b){return getx(a)<getx(b);}
inline bool cmpr(int a,int b){return gett(a)<gett(b);} void cdq(int l,int r){
if(l>=r){f[arr[l]]=max(f[arr[l]],f[arr[l]-]);return;}
int m=l+r>>,t=;
cdq(l,m);sort(arr+l,arr+m+,cmpl);
memcpy(tmp+m+,arr+m+,*(r-m));sort(arr+m+,arr+r+,cmpr);
for(int p=l;p<=m;p++){
while(t>=&&getk(stk[t],stk[t-])<getk(stk[t],arr[p])) t--;
stk[++t]=arr[p];
}for(int q=m+;q<=r;q++){
while(t>=&&getk(stk[t],stk[t-])<gett(arr[q])) t--;
int j=stk[t],i=arr[q];
f[i]=max(f[i],gety(j)*A[i]+getx(j)*B[i]);
}
memcpy(arr+m+,tmp+m+,*(r-m));cdq(m+,r);
} int main(){
//freopen("testdata.in","r",stdin);
//freopen(".out","w",stdout);
int i,j,k;
N=rd(),f[]=rd();
for(i=;i<=N;i++){
scanf("%lf%lf%lf",&A[i],&B[i],&R[i]);
arr[i]=i;
}cdq(,N);
double ans=;
for(i=;i<=N;i++){
ans=max(ans,f[i]);
}printf("%.3lf\n",ans);
return ;
}
bzoj1492/luogu4027 货币兑换 (斜率优化+cdq分治)的更多相关文章
-
LUOGU P4027 [NOI2007]货币兑换 (斜率优化+CDQ分治)
传送门 解题思路 题目里有两句提示一定要看清楚,要不全买要不全卖,所以dp方程就比较好列,f[i]=max(f[j]*rate[j]*a[i])/(rate[j]*a[j]+b[j])+(f[j]*b ...
-
BZOJ_3963_[WF2011]MachineWorks_斜率优化+CDQ分治
BZOJ_3963_[WF2011]MachineWorks_斜率优化+CDQ分治 Description 你是任意性复杂机器公司(Arbitrarily Complex Machines, ACM) ...
-
[BZOJ1492][NOI2007]货币兑换Cash(斜率优化+CDQ分治)
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 5838 Solved: 2345[Submit][Sta ...
-
【BZOJ-1492】货币兑换Cash DP + 斜率优化 + CDQ分治
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 3396 Solved: 1434[Submit][Sta ...
-
【BZOJ1492】[NOI2007]货币兑换Cash 斜率优化+cdq分治
[BZOJ10492][NOI2007]货币兑换Cash Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券(以下简称B券).每 ...
-
BZOJ.1492.[NOI2007]货币兑换(DP 斜率优化 CDQ分治/Splay)
BZOJ 洛谷 如果某天能够赚钱,那么一定会在这天把手上的金券全卖掉.同样如果某天要买,一定会把所有钱花光. 那么令\(f_i\)表示到第\(i\)天所拥有的最多钱数(此时手上没有任何金券),可以选择 ...
-
[Noi2014]购票 BZOJ3672 点分治+斜率优化+CDQ分治
Description 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会.全国的城市构成了一棵以SZ市为根的有根树,每个城市与它的 ...
-
洛谷.4655.[CEOI2017]Building Bridges(DP 斜率优化 CDQ分治)
LOJ 洛谷 \(f_i=s_{i-1}+h_i^2+\min\{f_j-s_j+h_j^2-2h_i2h_j\}\),显然可以斜率优化. \(f_i-s_{i-1}-h_i^2+2h_ih_j=f_ ...
-
BZOJ3963 WF2011MachineWorks(动态规划+斜率优化+cdq分治)
按卖出时间排序后,设f[i]为买下第i台机器后的当前最大收益,则显然有f[i]=max{f[j]+gj*(di-dj-1)+rj-pi},且若此值<0,应设为-inf以表示无法购买第i台机器. ...
随机推荐
-
oracle 安装注意
1. 本地安装oracle数据库后,并不代表可以用plsql 连接上了.. 如果安装的是64位的oracle,plsql 是不能直接连接的.. 2. 如果是64位的..需要下载一个oracle 客户端 ...
-
c++builder CryptoAPI md5
#include <wincrypt.h> DWORD GetHash( CONST BYTE * pbData, DWORD dwDataLen, ALG_ID algId, LPTST ...
-
Python标准库之urllib,urllib2
urllib模块提供了一些高级接口,用于编写需要与HTTP服务器交互的客户端.典型的应用程序包括从网页抓取数据.自动化.代理.网页爬虫等. 在Python 2中,urllib功能分散在几个不同的库模块 ...
-
java设计模式--行为型模式--备忘录模式
备忘录模式,我们平常所做的备忘录么.还得深深研究哦. 备忘录模式: 备忘录模式 概述 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状 ...
-
JAVA_SE基础——6.标识符&关键字
学会写helloworld之后, 我们就开始来认识标识符&关键字 一.标识符 标识符是指可被用来为类.变量或方法等命名的字符序列,换言之,标识符就是用户自定义的名称来标识类.变量或方法等.更 ...
-
Lucene.Net如何实现搜索结果分类统计功能
最近我们搜易站内搜索系统的一个客户需要一个无限级分类和分类统计功能,要实现的效果如下: 但由于搜易站内搜索系统是基于Lucene.net 2.0开发的,并没有内置的分类统计搜索功能,于是乎只能自己实现 ...
-
Kafka 处理器客户端介绍
[编者按]本文作者为 Bill Bejeck,主要介绍如何有效利用新的 Apache Kafka 客户端来满足数据处理需求.文章系国内 ITOM 管理平台 OneAPM 编译呈现,以下为正文. 如果你 ...
-
Server Tomcat v8.0 Server at localhost failed to start.的解决方法
1.可能是web.xml中的filter-mapping中url-pattern没加/* 2.可能是servlet和servlet-mapping中的servlet-name不匹配
-
[C#][控件]WebBrowser 使用范例
if (webInfo.Document != null) webInfo.Document.OpenNew(true); else webInfo.Navigate("about:blan ...
-
一步一步学EF系列三【数据迁移】
我们每篇的内容都不多,所以希望在学习的过程中最后能亲自敲一下代码 这样更有利于掌握. 我们现在接着上篇的例子,我们现在给随便的表增加一个字段 CreateTime 创建日期 运行一下 看看会怎么样 修 ...