BZOJ 1492: [NOI2007]货币兑换Cash [CDQ分治 斜率优化DP]
题意:不想写...
好吧我回来了
首先发现每次兑换一定是全部兑换,因为你兑换说明有利可图,是为了后面的某一天两种卷的汇率差别明显而兑换
那么一定拿全利啊,一定比多天的组合好
$f[i]$表示第$i$天最多能得到的钱在这一天可以换成多少$A$卷
枚举使用哪一天留下的卷,按这一天的汇率换成钱来更新最大钱数
再用这个钱数更新$f[i]$
这样是$O(n^2)$的
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
typedef long long ll;
const int N=1e5+,M=1e4+;
const double eps=1e-;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,s;
double a[N],b[N],r[N];
double f[N];
void dp(){
f[]=s*r[]/(a[]*r[]+b[]);
double t=s;
for(int i=;i<=n;i++){
for(int j=;j<i;j++) t=max(t,f[j]*a[i]+f[j]/r[j]*b[i]);
f[i]=max(f[i],t*r[i]/(a[i]*r[i]+b[i]));
}
printf("%.3lf",t);
}
int main(){
freopen("in","r",stdin);
n=read();s=read();
for(int i=;i<=n;i++) scanf("%lf%lf%lf",&a[i],&b[i],&r[i]);
dp();
}
DP-naive
然后发现这个式子可以斜率优化
假设转移$j$比$k$更优,且$f_j<f_k$
令$g_i=\frac{f_i}{r_i}$
$\frac{g_k-g_j}{f_k-f_j}\ <\ -\frac{a_i}{b_i}$
然后$f$不单调,所以用平衡树或者CDQ分治来维护
$CDQ$分治里左面按$x$排序,右面按$k$排序
注意:
CDQ分治中$l$和$1$一定别打错.........我$Debug$了好长时间
比较斜率的时候要$+eps$,精度太玄学了呜呜呜
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=1e5+;
const double eps=1e-;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n;
double d[N];
struct Day{
double a,b,r,k,x,y;
int id;
bool operator <(const Day &r)const{return k>r.k;}
}p[N],t[N];
inline bool cmp(Day &a,Day &b){//a<b
return a.x<b.x||(abs(a.x-b.x)<eps&&a.y<b.y);
}
inline double slope(int a,int b){
if(abs(p[a].x-p[b].x)<eps) return 1e20;
else return (p[a].y-p[b].y)/(p[a].x-p[b].x);
}
int st[N],top;
void Solve(int l,int r){//printf("Solve %d %d\n",l,r);
if(l==r){
d[l]=max(d[l],d[l-]);
p[l].y=d[l]/(p[l].a*p[l].r+p[l].b);
p[l].x=p[l].y*p[l].r;
return;
}
int mid=(l+r)>>,p1=l,p2=mid+;
for(int i=l;i<=r;i++){
if(p[i].id<=mid) t[p1++]=p[i];
else t[p2++]=p[i];
}
for(int i=l;i<=r;i++) p[i]=t[i]; Solve(l,mid);
top=;
for(int i=l;i<=mid;i++){
while(top>&&slope(st[top-],st[top])<slope(st[top-],i)+eps) top--;
st[++top]=i;//printf("st %d\n",i);
}
//
int j=;
for(int i=mid+;i<=r;i++){
while(j<top&&slope(st[j],st[j+])+eps>p[i].k) j++;
d[p[i].id]=max(d[p[i].id],p[st[j]].x*p[i].a+p[st[j]].y*p[i].b);
}
Solve(mid+,r);
p1=l;p2=mid+;
for(int i=l;i<=r;i++){
if(p1<=mid&&( p2>r||cmp(p[p1],p[p2]) )) t[i]=p[p1++];
else t[i]=p[p2++];
}
for(int i=l;i<=r;i++) p[i]=t[i];
}
int main(){
//freopen("in","r",stdin);
freopen("cash.in","r",stdin);
freopen("cash.out","w",stdout);
n=read();d[]=read();
for(int i=;i<=n;i++)
scanf("%lf%lf%lf",&p[i].a,&p[i].b,&p[i].r),
p[i].k=-p[i].a/p[i].b,p[i].id=i;
sort(p+,p++n);
Solve(,n);
//for(int i=1;i<=n;i++) printf("hi %d %d %lf\n",i,p[i].id,d[i]);
printf("%.3lf",d[n]);
return ;
}
BZOJ 1492: [NOI2007]货币兑换Cash [CDQ分治 斜率优化DP]的更多相关文章
- bzoj1492[NOI2007]货币兑换Cash cdq分治+斜率优化dp
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 5541 Solved: 2228[Submit][Sta ...
- bzoj 1492: [NOI2007]货币兑换Cash【贪心+斜率优化dp+cdq】
参考:http://www.cnblogs.com/lidaxin/p/5240220.html 虽然splay会方便很多,但是懒得写,于是写了cdq 首先要想到贪心的思路,因为如果在某天买入是能得到 ...
- [BZOJ1492] [NOI2007] 货币兑换Cash(cdq分治+斜率优化)
[BZOJ1492] [NOI2007] 货币兑换Cash(cdq分治+斜率优化) 题面 分析 dp方程推导 显然,必然存在一种最优的买卖方案满足:每次买进操作使用完所有的人民币:每次卖出操作卖出所有 ...
- BZOJ1492:[NOI2007]货币兑换 (CDQ分治+斜率优化DP | splay动态维护凸包)
BZOJ1492:[NOI2007]货币兑换 题目传送门 [问题描述] 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和B纪念券(以下简称B券).每个持有金券的 ...
- BZOJ 1492 [NOI2007]货币兑换Cash (CDQ分治/splay 维护凸包)
题目大意:太长了略 splay调了两天一直WA弃疗了 首先,我们可以猜一个贪心,如果买/卖,就一定都买/卖掉,否则不买/卖 反正货币的行情都是已知的,没有任何风险,所以肯定要选择最最最优的方案了 容易 ...
- BZOJ 3963 HDU3842 [WF2011]MachineWorks cdq分治 斜率优化 dp
http://acm.hdu.edu.cn/showproblem.php?pid=3842 写的check函数里写的<但是应该是<=,调了一下午,我是个zz. 就是普通的斜率优化因为有两 ...
- 【uoj#244】[UER #7]短路 CDQ分治+斜率优化dp
题目描述 给出 $(2n+1)\times (2n+1)$ 个点,点 $(i,j)$ 的权值为 $a[max(|i-n-1|,|j-n-1|)]$ ,找一条从 $(1,1)$ 走到 $(2n+1,2n ...
- 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的数量. 然后就很明显了...平衡 ...
- ●BZOJ 1492 [NOI2007]货币兑换Cash
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1492 题解: 斜率优化DP,CDQ分治 定义$DP[i]$为第i天结束后的最大收益. 由于题 ...
随机推荐
- 基于Echarts4.0实现旭日图
昨天Echarts4.0正式发布,随着4.0而来的是一系列的更新,挑几个主要的简单说明: 1.展示方面通过增量渲染技术(4.0+)ECharts 能够展现千万级的数据量 2.针对移动端优化,移动端小屏 ...
- 完整CentOS搭建OpenVPN服务详细教程
一.介绍 1.定义 ① OpenVPN是一个用于创建虚拟专用网络加密通道的软件包,最早由James Yonan编写.OpenVPN允许创建的VPN使用公开密钥.电子证书.或者用户名/密码来进行身份验证 ...
- NYOJ 1248 海岛争霸(Dijkstra变形——最短路径最大权值)
题目链接: http://acm.nyist.net/JudgeOnline/problem.php?pid=1248 描述 神秘的海洋,惊险的探险之路,打捞海底宝藏,激烈的海战,海盗劫富等等.加勒比 ...
- 用NPOI导出Excel,生成下拉列表、以及下拉联动列表(第1篇/共3篇)
最近帅帅的小毛驴遇到一个很奇葩的需求: 导出Excel报表,而且还要带下拉框,更奇葩的是,下拉框还是联动的. 小毛驴一天比较忙,所以这等小事自然由我来为她分忧了.经历了两天,做了几种解决方案,最后完美 ...
- php网站在服务器上邮件发送不了,在本地可以
标签: php邮箱 2015-11-27 13:58 879人阅读 评论(0) 收藏 举报 分类: php(2) 版权声明:本文为博主原创文章,未经博主允许不得转载. 最近在做phpmailer发送邮 ...
- PHP批量去除bom头代码的小工具
在 aitecms 群里有网友抱怨了好几天说本地的验证码一直无法显示,后来听说解决了,问其如何解决的,说是去除了文件 bom 就好了.后来百度到一篇文章也说 dedecms 的验证码不能显示,某次解决 ...
- SSL协议之数据加密过程详解
前言 总括: 原文博客地址:SSL协议之数据加密过程详解 知乎专栏&&简书专题:前端进击者(知乎)&&前端进击者(简书) 博主博客地址:Damonare的个人博客 生活 ...
- CSS background-clip 属性
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- Spring整合Struts的两种方式介绍
1 使用Spring托管Struts Action 该种方式就是将Struts Action也视为一种Bean交给Spring来进行托管,使用时Struts的配置文件中配置的Action的classs ...
- pip install在Windows下报错解决
报错: Traceback (most recent call last): File, in<module> load_entry_point('pip==1.4.1','console ...