BZOJ 1492 [NOI2007] - cash
Description
最初你有 S 块钱, 有 N 天给你来兑换货币, 求最大获利.
一共只有两种货币 A , B .
对于每一天, 给定 3 个系数 A[i], B[i], Rate[i]
A[i] 表示当天 A 货币的单位价值, B[i] 表示当前 B 货币的单位价值.
第\(i\)天你可以进行以下两种操作: (可以执行多次)
① 将 OP% 的 A 货币和 OP% 的 B 货币卖出.
② 按照 A : B = Rate[i] 的比例, 用一部分的钱买入货币.
\(n \le 100000\)
Analysis
考虑假如有一天买货币没有用完所有钱更优, 说明这里的前用了后面赚不回来
同理可知: 要么一次性买入货币买光所有钱, 要么一次卖光所有货币
我们将相邻的买卖分为一组
记\(f[i]\)为第\(i\)天(在买之前)最多能有多少钱
于是\(f[i] = \max\{f[i-1], D[j] * A[i] + C[j] * B[i]\}\)
其中\(C[i] = \frac{f[i]}{A[i]*Rate[i] + B[i]}\) 即花光钱能买多少个\(B\)货币
\(D[i] = C[i] * Rate[i]\)即花光钱能买多少个\(A\)货币
这是一个可以斜率优化的式子.
但是注意到\(A,B,C,D\)什么的都并没有单调性
Solution 1
动态维护凸壳
Solution 2
注意到转移只与前面求出来的量有关
那么我们可以进行cdq分治
这样我们就可以排序建凸包, 排序切线询问.
Notice
不是一般序列上的斜率优化, 最好使用\(\det\)
对于切线询问, 除了可以用斜率判, 也可以直接根据答案的单峰性判断, 具体见代码
另外, 凸包比较还是用\(\le ,\ge\)这两个符号好一些
Code
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
#include <iostream>
#define rep(i,a,b) for (int i = (a); i <= (b); ++ i)
#define per(i,a,b) for (int i = (a); i >= (b); -- i)
#define For(i,a,b) for (int i = (a); i < (b); ++ i)
using namespace std;
const int M = 1e5 + 7;
typedef double db;
inline int ri(){
int x = 0; bool f = 1; char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = 0;
for (; isdigit(c); c = getchar()) x = x*10+c-48;
return f ? x : -x;
}
int n;
db f[M];
db A[M], B[M], C[M], D[M], R[M];
inline db det(db x, db y, db vx, db vy) {return x * vy - y * vx;}
inline bool side(int x, int y, int z) {return det(D[y]-D[x], C[y]-C[x], D[z]-D[x], C[z]-C[x]) >= 0;}
inline db calc(int x, int y) {return D[x] * A[y] + C[x] * B[y];}
inline db V(int x) {return - A[x] / B[x];}
inline bool cmp1(int x, int y) {return D[x] < D[y];}
inline bool cmp2(int x, int y) {return V(x) > V(y);}
void cdq(int l, int r){
static int q[M], v[M];
if (l == r) {
f[l] = max(f[l], f[l-1]);
C[l] = f[l] / (A[l] * R[l] + B[l]);
D[l] = C[l] * R[l];
return;
}
int mid = l+r >> 1;
cdq(l, mid);
rep (i, l, mid) q[i] = i;
sort(q+l, q+mid+1, cmp1);
int h = l, t = l-1;
rep (i, l, mid){
while (h < t && side(q[t-1], q[t], q[i]) ) --t;
q[++t] = q[i];
}
rep (i, mid+1, r) v[i] = i;
sort(v+mid+1, v+r+1, cmp2);
rep (i, mid+1, r){
int y = v[i];
while (h < t && calc(q[h], y) <= calc(q[h+1], y)) ++h;
f[y] = max(f[y], calc(q[h], y));
}
cdq(mid+1, r);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("a.in", "r", stdin);
#endif
scanf("%d%lf", &n, &f[0]);
rep (i, 1, n) scanf("%lf%lf%lf", &A[i], &B[i], &R[i]);
cdq(1, n);
printf("%.3lf\n", f[n]);
return 0;
}
BZOJ 1492 [NOI2007] - cash的更多相关文章
- 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天结束后的最大收益. 由于题 ...
- bzoj 1492 [NOI2007]货币兑换Cash(斜率dp+cdq分治)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1492 [题意] 有AB两种货币,每天可以可以付IPi元,买到A券和B券,且A:B= ...
- 斜率优化(CDQ分治,Splay平衡树):BZOJ 1492: [NOI2007]货币兑换Cash
Description Input 第一行两个正整数N.S,分别表示小Y 能预知的天数以及初始时拥有的钱数. 接下来N 行,第K 行三个实数AK.BK.RateK,意义如题目中所述 Output 只有 ...
- BZOJ 1492: [NOI2007]货币兑换Cash [CDQ分治 斜率优化DP]
传送门 题意:不想写... 扔链接就跑 好吧我回来了 首先发现每次兑换一定是全部兑换,因为你兑换说明有利可图,是为了后面的某一天两种卷的汇率差别明显而兑换 那么一定拿全利啊,一定比多天的组合好 $f[ ...
- bzoj 1492: [NOI2007]货币兑换Cash
Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券(以下 简称B券).每个持有金券的顾客都有一个自己的帐户.金券的数目可以是一个 ...
- BZOJ 1492 [NOI2007]货币兑换Cash:斜率优化dp + cdq分治
传送门 题意 初始时你有 $ s $ 元,接下来有 $ n $ 天. 在第 $ i $ 天,A券的价值为 $ A[i] $ ,B券的价值为 $ B[i] $ . 在第 $ i $ 天,你可以进行两种操 ...
- bzoj 1492: [NOI2007]货币兑换Cash【贪心+斜率优化dp+cdq】
参考:http://www.cnblogs.com/lidaxin/p/5240220.html 虽然splay会方便很多,但是懒得写,于是写了cdq 首先要想到贪心的思路,因为如果在某天买入是能得到 ...
- BZOJ 1492 [NOI2007]货币兑换Cash (CDQ分治/splay 维护凸包)
题目大意:太长了略 splay调了两天一直WA弃疗了 首先,我们可以猜一个贪心,如果买/卖,就一定都买/卖掉,否则不买/卖 反正货币的行情都是已知的,没有任何风险,所以肯定要选择最最最优的方案了 容易 ...
随机推荐
- HTML5--定义区块
1.效果图如下: 备注: <article> 1.作用:用来表示文档.页面中独立的.完整的.可以独自被外部引用的内容 2.一般有个header元素,有时还有脚注 <article&g ...
- 如何在nlp问题中定义自己的数据集
我之前大致写了一篇在pytorch中如何自己定义数据集合,在这里如何自定义数据集 不过这个例子使用的是image,也就是图像.如果我们用到的是文本呢,处理的是NLP问题呢? 在解决这个问题的时候,我在 ...
- 【Sklearn系列】使用Sklearn进行数据预处理
这篇文章主要讲解使用Sklearn进行数据预处理,我们使用Kaggle中泰坦尼克号事件的数据作为样本. 读取数据并创建数据表格,查看数据相关信息 import pandas as pd import ...
- C++基础 const
1. C中的const C中const变量只是只读变量,有自己存储空间.可能被存放在 栈.堆.数据段,所以可以修改. 2. C++中const 可能分配空间,也可能不分配空间. 当 const 为全局 ...
- 笔记-redis安装
笔记-redis安装配置 1. redis安装配置 1.1. windows环境安装 win8已有redis 查看版本:redis-server –version 想更新到5.0.0, ...
- HDFS HA 的 core-site.xml
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <!-- Licens ...
- 一、MySQL数据库之简介和安装
一.基础部分 1.数据库是简介 之前所学,数据要永久保存,比如用户注册的用户信息,都是保存于文件中,而文件只能存在于某一台机器上. 如果我们不考虑从文件中读取数据的效率问题,并且假设我们的程序 ...
- Dragger 2遇到的坑 Dragger2详解 Dragger2学习最好的资料
我是曹新雨,我为自己代言.现在的菜鸟,3年以后我就是大神.为自己加油.微信:aycaoxinyu Dragger2是什么,我就不再说了.资料一堆,而且里面的注解什么意思,我推荐两篇文章,这两篇都是我精 ...
- “管中窥豹”,MyCAT的基因缺陷
提起MyCAT,我的脑海里,总是浮现出这样一首偈.弘忍觉得自己老了,需要找一个接班人,于是,弘忍要求弟子们每人写一个偈子,根据偈子观察各位弟子的开悟程度,从而传授正宗禅宗的衣钵.弟子们心里其实都很明白 ...
- DOS程序员手册(三)
56页 第4章DOS和BIOS接口 本章介绍了用户程序访问DOS内核和BIOS所提供的各种服务的方法.为了访问这 些服务,我们可以从任何编程语言中调用各个软件中断,这些中断便是我们在本 ...