cdq分治入门--BZOJ1492: [NOI2007]货币兑换Cash
n<=100000天,一开始有s块钱,每天股票A价格ai,B价格bi,每天可以做的事情:卖出股票;按A:B=RTi的比例买入股票。问最后的最大收益。股票可以为浮点数,答案保留三位。
用脚指头想想就知道是:某一天全部买进来,某一天全部卖出去,没有说买一半卖一半的。
那就可以dp了,f(i)表示前i天最大收益,,其中Xi表示用f(i)块钱在第i天能买多少A券,Yi表示f(i)块前第i天买多少B券,可以自己算,n方过不了。
现要找max(Ai*Xj+Bi*Yj),考虑两个状态j,k,j比k优时
整理得,前提是Xj>Xk
那就平衡树维护一下一个递增的(Yj-Yk)/(Xj-Xk),即维护一个凸包即可,难写,略。
cdq就是这样把一个在线的东西强行转化成离线。
solve(l,r)表示把这个区间里的f算完,solve(l,mid)之后,用(l,mid)的状态更新(mid+1,r)的状态,然后solve(mid+1,r),这就是一个分治。
为了使这个更新过程顺利完成,在solve(l,mid)时需要找到这个凸包,可以通过维护Xi的单调,然后直接一个栈保存单调的斜率即可;mid+1到r这一段,也需要保证-Ai/Bi的单调,这个可以预处理出来。现在就是一个离线问题,一边凸包单增被离线实现了,一边-Ai/Bi预处理排序好了,那就可以两个指针直接扫一遍更新了。
trick!!(Xj-Xk)可能等于0。。。。。。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<math.h>
//#include<iostream>
using namespace std; int n,s;
#define maxn 200011
double a[maxn],b[maxn],rt[maxn]; int num[][maxn];
void mergesort(int L,int R,int cur)
{
if (L==R)
{
num[cur][L]=L;
return;
}
const int mid=(L+R)>>;
mergesort(L,mid,cur+),mergesort(mid+,R,cur+);
int i=L,j=mid+,k=i;
while (i<=mid && j<=R)
{
if (-a[num[cur+][i]]/b[num[cur+][i]]>-a[num[cur+][j]]/b[num[cur+][j]])
num[cur][k++]=num[cur+][i++];
else num[cur][k++]=num[cur+][j++];
}
while (i<=mid) num[cur][k++]=num[cur+][i++];
while (j<=R) num[cur][k++]=num[cur+][j++];
} double f[maxn],xx[maxn],yy[maxn];int sta[maxn],top,numf[][maxn];
double calc(int i,int j) {return fabs(xx[i]-xx[j])>1e-?(yy[i]-yy[j])/(xx[i]-xx[j]):1e300;}
//i>j
void solve(int L,int R,int cur)
{
if (L==R)
{
numf[cur][L]=L;
f[L]=max(f[L],f[L-]);
yy[L]=f[L]/(rt[L]*a[L]+b[L]);
xx[L]=f[L]*rt[L]/(rt[L]*a[L]+b[L]);
return;
}
const int mid=(L+R)>>;
solve(L,mid,cur+);
top=;
for (int i=L;i<=mid;i++)
{
const int id=numf[cur+][i];
while (top> && calc(id,sta[top])-calc(sta[top],sta[top-])>-1e-) top--;
sta[++top]=id;
}
for (int i=mid+,j=;i<=R;i++)
{
const int &id=num[cur+][i];
while (j<top && -a[id]/b[id]-calc(sta[j+],sta[j])<1e-) j++;
f[id]=max(f[id],a[id]*xx[sta[j]]+b[id]*yy[sta[j]]);
}
solve(mid+,R,cur+);
int i=L,j=mid+,k=i;
while (i<=mid && j<=R)
{
if (xx[numf[cur+][i]]<xx[numf[cur+][j]]) numf[cur][k++]=numf[cur+][i++];
else numf[cur][k++]=numf[cur+][j++];
}
while (i<=mid) numf[cur][k++]=numf[cur+][i++];
while (j<=R) numf[cur][k++]=numf[cur+][j++];
} int main()
{
scanf("%d%d",&n,&s);
for (int i=;i<=n;i++) scanf("%lf%lf%lf",&a[i],&b[i],&rt[i]);
mergesort(,n,);
// for (int i=0;i<=2;i++){
// for (int j=1;j<=n;j++)
// cout<<(-a[num[i][j]]/b[num[i][j]])<<' ';cout<<endl;}
f[]=s;for (int i=;i<=n;i++) f[i]=;
solve(,n,);
// for (int i=1;i<=n;i++) cout<<f[i]<<' ';cout<<endl;
printf("%.3f\n",f[n]);
return ;
}
cdq分治入门--BZOJ1492: [NOI2007]货币兑换Cash的更多相关文章
- [BZOJ1492] [NOI2007] 货币兑换Cash(cdq分治+斜率优化)
[BZOJ1492] [NOI2007] 货币兑换Cash(cdq分治+斜率优化) 题面 分析 dp方程推导 显然,必然存在一种最优的买卖方案满足:每次买进操作使用完所有的人民币:每次卖出操作卖出所有 ...
- [BZOJ1492][NOI2007]货币兑换Cash(斜率优化+CDQ分治)
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 5838 Solved: 2345[Submit][Sta ...
- bzoj1492[NOI2007]货币兑换Cash cdq分治+斜率优化dp
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 5541 Solved: 2228[Submit][Sta ...
- BZOJ1492: [NOI2007]货币兑换Cash 【dp + CDQ分治】
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MB Submit: 5391 Solved: 2181 [Submit][S ...
- [BZOJ1492] [NOI2007]货币兑换Cash 斜率优化+cdq/平衡树维护凸包
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 5907 Solved: 2377[Submit][Sta ...
- bzoj千题计划237:bzoj1492: [NOI2007]货币兑换Cash
http://www.lydsy.com/JudgeOnline/problem.php?id=1492 dp[i] 表示 第i天卖完的最大收益 朴素的dp: 枚举从哪一天买来的在第i天卖掉,或者是不 ...
- bzoj1492 [NOI2007]货币兑换Cash【cdq分治】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1492 推荐博客:http://www.cnblogs.com/zig-zag/archive ...
- Bzoj1492: [NOI2007]货币兑换Cash(不单调的斜率优化)
题面 传送门 Sol 题目都说了 必然存在一种最优的买卖方案满足: 每次买进操作使用完所有的人民币: 每次卖出操作卖出所有的金券. 设\(f[i]\)表示第\(i\)天可以有的最大钱数 枚举\(j&l ...
- BZOJ1492: [NOI2007]货币兑换Cash(CDQ分治,斜率优化动态规划)
Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券(以下 简称B券).每个持有金券的顾客都有一个自己的帐户.金券的数目可以是一个 ...
随机推荐
- 【转】JAVA的静态变量、静态方法、静态类
转自:http://blog.csdn.net/zhandoushi1982/article/details/8453522/ 静态变量和静态方法都属于静态对象,它与非静态对象的差别需要做个说明. ( ...
- angular.module 参数的意思
定义一个module需要两个参数,第一个作为module的名字,第二个则是指出这个module都依赖哪些别的modules
- webapp开发学习---Cordova目录结构分析及一些概念
Config.xml是一个全局配置文件,用于控制cordova应用程序行为的许多方面. 这个不依赖于平台的XML文件是基于W3C的“打包Web应用程序(Widget)”规范进行安排的,并扩展到指定 ...
- (1)《Head First HTML与CSS》学习笔记---HTML基本概念
前言: 1. 这本书并没有面面俱到,涵盖所有内容,只提供作为初学者真正需要的东西:基本知识和信心.所以这不是唯一的参考书.(我买了一本<HTML5权威指南>作为参考书和这本一起看, ...
- git---安装及配置
git官网:https://git-scm.com 安装: 官网下载->一路Next->安装完成 配置git: 1.win+r进入windows命令行 2.注册: git config - ...
- 把Scheme翻译成Java和C++的工具
一.为什么要写这个工具? 公司内容有多个项目需要同一个功能,而这些项目中,有的是用Java的,有的是用C++的,同时由于某些现实条件限制,无法所有项目都调用统一的服务接口(如:可能运行在无网络的情况下 ...
- Code::Blocks使用与调试一条龙
CodeBlocks创建C语言工程版本13.12 选择"create a new project" 选择第四个,点击"go" 4 选择"C&quo ...
- 迅为嵌入式4412平台兼容3G/4G模块的安卓开发板
安卓开发板特点说明: 1. 配备16G固态硬盘EMMC存储 2. 64位双通道2GB内存 三星S5M8767电源管理 板载高精度GPS模块 CAN,RS-485等工业接口 板载WIFI蓝牙模块,陀螺仪 ...
- Discuz3.1登录QQ互联显示redirect uri is illegal(100010)的解决
QQ互联最近也是BUG不断,引起了很多用户的不满,从早前关闭群组功能,到发布2.0接口标准,引发系列站长用户的连锁反应.而Discuz从X3开始,为了应对QQ互联的2.0接口标准,采用了云平台来整合Q ...
- vue之loader处理静态资源
webpack 是利用loader 来处理各种资源的,wepback的配置基本上就是为各种资源文件,指定不同类型的loader. 1,处理css 最基本的css 处理loader 是css-loade ...