dp(i) = max(dp(i-1), x[j]*a[i]+y[j]*b[i]), 0<j<i. x, y表示某天拥有的最多钱去买金券, 金券a和金券b的数量. 然后就很明显了...平衡树维护上凸壳, 询问时就在凸壳上二分...时间复杂度O(NlogN)

-----------------------------------------------------------------------------------------------

#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
 
using namespace std;
 
#define K(a, b) ((a.y - b.y) / (a.x - b.x))
 
const int maxn = 100009;
const double eps = 1e-7;
const double INF = 1e100;
 
double dp, A, B, R, K;
int N;
 
struct P {
double x, y;
P(double _x = 0, double _y = 0) : x(_x), y(_y) {
}
bool operator < (const P &p) const {
return x < p.x;
}
bool operator == (const P &p) const {
return fabs(x - p.x) < eps && fabs(y - p.y) < eps;
}
} p;
 
struct Node {
Node* ch[2];
double lk, rk;
int r;
P p;
} pool[maxn], *pt, *Root, *Null;
 
void Init_Treap() {
pt = pool;
pt->ch[0] = pt->ch[1] = pt;
pt->p = P(-INF, -INF);
Root = Null = pt++;
}
 
void Rotate(Node*&t, int d) {
Node* o = t->ch[d ^ 1];
t->ch[d ^ 1] = o->ch[d];
o->ch[d] = t;
t = o;
}
 
void Insert(Node*&t) {
if(t == Null) {
(t = pt++)->p = p, t->r = rand();
t->ch[0] = t->ch[1] = Null;
} else {
int d = (t->p < p);
Insert(t->ch[d]);
if(t->ch[d]->r > t->r) Rotate(t, d ^ 1);
}
}
 
void Delete(Node*&t) {
int d = (p == t->p ? -1 : (t->p < p));
if(d == -1) {
if(t->ch[0] != Null && t->ch[1] != Null) {
int _d = (t->ch[0]->r > t->ch[1]->r);
Rotate(t, _d), Delete(t->ch[_d]);
} else
t = (t->ch[0] != Null ? t->ch[0] : t->ch[1]);
} else 
Delete(t->ch[d]);
}
 
Node* Pred(P &p) {
Node* ret = Null;
for(Node* o = Root; o != Null; ) if(o->p < p)
ret = o, o = o->ch[1];
else
o = o->ch[0];
return ret;
}
 
Node* Succ(P &p) {
Node* ret = Null;
for(Node* o = Root; o != Null; ) if(p < o->p)
ret = o, o = o->ch[0];
else
o = o->ch[1];
return ret;
}
 
Node* Find(P &p) {
for(Node* t = Root; t != Null; ) {
if(fabs(t->p.x - p.x) < eps) return t;
t = (p.x < t->p.x ? t->ch[0] : t->ch[1]);
}
return 0;
}
 
P Select(Node*&t) {
if(t->r == -1) return Select(t->ch[1]);
if(t->r == -2) return Select(t->ch[0]);
if(K - t->lk < eps && t->rk - K < eps) return t->p;
return K - t->lk > eps ? Select(t->ch[0]) : Select(t->ch[1]);
}
 
void Init() {
Init_Treap();
p = P(0, -INF), Insert(Root);
p = P(1e10, -INF), Insert(Root);
Node* t = pt;
(--t)->r = -2, (--t)->r = -1;
}
 
void Add() {
double b = dp / (A * R + B), a = b * R;
P o = P(a, b);
Node *t = Find(o);
if(t) {
if(t->p.y - o.y > eps) return;
p = t->p, Delete(Root);
}
Node *L = Pred(o), *R = Succ(o);
if(R->p == o || K(o, R->p) - K(o, L->p) > eps) return;
for(Node* LL = Pred(L->p); LL != Null; ) {
if(K(o, L->p) - K(L->p, LL->p) > eps)
p = L->p, Delete(Root);
else
break;
L = LL, LL = Pred(L->p);
}
pt->lk = L->rk = K(L->p, o);
for(Node* RR = Succ(R->p); RR != Null; ) {
if(K(RR->p, R->p) - K(R->p, o) > eps)
p = R->p, Delete(Root);
else
break;
R = RR, RR = Succ(R->p);
}
R->lk = pt->rk = K(R->p, o);
p = o, Insert(Root);
}
 
void Work() {
scanf("%d%lf", &N, &dp);
for(int i = 0; i < N; i++) {
scanf("%lf%lf%lf", &A, &B, &R);
if(i) {
K = -A / B;
P o = Select(Root);
dp = max(dp, A * o.x + B * o.y);
}
Add();
}
printf("%.3lf\n", dp);
}
 
int main() {
Init();
Work();
return 0;
}

-----------------------------------------------------------------------------------------------

1492: [NOI2007]货币兑换Cash

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 2843  Solved: 1201
[Submit][Status][Discuss]

Description

Input

第一行两个正整数N、S,分别表示小Y 能预知的天数以及初始时拥有的钱数。 接下来N 行,第K 行三个实数AK、BK、RateK,意义如题目中所述

Output

只有一个实数MaxProfit,表示第N 天的操作结束时能够获得的最大的金钱 数目。答案保留3 位小数。

Sample Input

3 100
1 1 1
1 2 2
2 2 3

Sample Output

225.000

HINT

测试数据设计使得精度误差不会超过10-7。
对于40%的测试数据,满足N ≤ 10;
对于60%的测试数据,满足N ≤ 1 000;
对于100%的测试数据,满足N ≤ 100 000;

Source

BZOJ 1492: [NOI2007]货币兑换Cash( dp + 平衡树 )的更多相关文章

  1. BZOJ 1492: [NOI2007]货币兑换Cash [CDQ分治 斜率优化DP]

    传送门 题意:不想写... 扔链接就跑 好吧我回来了 首先发现每次兑换一定是全部兑换,因为你兑换说明有利可图,是为了后面的某一天两种卷的汇率差别明显而兑换 那么一定拿全利啊,一定比多天的组合好 $f[ ...

  2. bzoj 1492 [NOI2007]货币兑换Cash(斜率dp+cdq分治)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1492   [题意] 有AB两种货币,每天可以可以付IPi元,买到A券和B券,且A:B= ...

  3. 斜率优化(CDQ分治,Splay平衡树):BZOJ 1492: [NOI2007]货币兑换Cash

    Description Input 第一行两个正整数N.S,分别表示小Y 能预知的天数以及初始时拥有的钱数. 接下来N 行,第K 行三个实数AK.BK.RateK,意义如题目中所述 Output 只有 ...

  4. BZOJ 1492 [NOI2007]货币兑换Cash:斜率优化dp + cdq分治

    传送门 题意 初始时你有 $ s $ 元,接下来有 $ n $ 天. 在第 $ i $ 天,A券的价值为 $ A[i] $ ,B券的价值为 $ B[i] $ . 在第 $ i $ 天,你可以进行两种操 ...

  5. bzoj 1492: [NOI2007]货币兑换Cash【贪心+斜率优化dp+cdq】

    参考:http://www.cnblogs.com/lidaxin/p/5240220.html 虽然splay会方便很多,但是懒得写,于是写了cdq 首先要想到贪心的思路,因为如果在某天买入是能得到 ...

  6. ●BZOJ 1492 [NOI2007]货币兑换Cash

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1492 题解: 斜率优化DP,CDQ分治 定义$DP[i]$为第i天结束后的最大收益. 由于题 ...

  7. BZOJ 1492 [NOI2007]货币兑换Cash (CDQ分治/splay 维护凸包)

    题目大意:太长了略 splay调了两天一直WA弃疗了 首先,我们可以猜一个贪心,如果买/卖,就一定都买/卖掉,否则不买/卖 反正货币的行情都是已知的,没有任何风险,所以肯定要选择最最最优的方案了 容易 ...

  8. BZOJ 1492: [NOI2007]货币兑换Cash 斜率优化 + splay动态维护凸包

    Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券(以下 简称B券).每个持有金券的顾客都有一个自己的帐户.金券的数目可以是一个 ...

  9. bzoj 1492: [NOI2007]货币兑换Cash

    Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券(以下 简称B券).每个持有金券的顾客都有一个自己的帐户.金券的数目可以是一个 ...

随机推荐

  1. ubuntu系统下设置静态IP

    改动 /etc/network/interfaces文件 加入下面内容 # The loopback network interface auto lo eth0 iface lo inet loop ...

  2. gcc中-pthread和-lpthread的区别

    最近在使用linux mint15,里面自带的gcc时4.7的,当我编译多线程程序时,使用-lpthread居然说没有找到线程库函数!!!然后man了一下,才发现在gcc 4.7中链接线程库使用-pt ...

  3. 【邻接表字符串Hash】【HDU1800】Flying to the Mars

    题意: 给你N个数字,带前导0,问出现最多的数字个数 思路: 读入,清楚前导0,Hash. 用邻接表字符串Hash有一下几点注意 string,不要memset,否则地址也没了,涉及到stl的东西,少 ...

  4. vs2015 不支持javascript的智能提示高亮

    有些人安装了vs2015后发现居然不支持javascrpt的高亮功能,连工具-选项-文本编辑器里面的javascript也没有了,楼主也碰到这么个情况了,估计是有与装了多个版本的原因,楼主电脑安装了V ...

  5. MySQL的group_concat与Oracle的wm_concat使用区别

    Oracle的wm_concat在拼接时,如果字段内容为空结果为空,null类型相加不受影响. MySQL的group_concat拼接时,如果不设置Separator,字段内容为空时不会得到空的结果 ...

  6. oracle日期函数集锦

    oracle 中select TO_CHAR(sysdate,'Mon') from dual; Question:出来是中文的“6月” 我想要英文的怎么办? Answer:select to_cha ...

  7. Quartz 2D 概述

    Quartz 2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境.我们可以使用Quartz 2D API来实现许多功能,如基本路径的绘制.透明度.描影.绘制阴影.透明层.颜色管理.反锯齿 ...

  8. <转>eclipse如何修改dynamic web module version .

         --------------------------------------------------------------------------------------------- 原 ...

  9. Yaf-Plus 我们只谈框架这件事

    预热下,也算对自己的督促. Comming soon!

  10. 在Windows的CMD中如何设置支持UTF8编码

    这个问题很多人开始都会不知道,当然包括曾经的我,当用到的时候,只好求助于伟大的股沟和度娘了.网上有设置的方法,但说明确不够详细系统,说设置字体为:Lucida Console.问题是,在默认方式下,只 ...