http://www.lydsy.com/JudgeOnline/problem.php?id=1492

dp[i] 表示 第i天卖完的最大收益

朴素的dp:

枚举从哪一天买来的在第i天卖掉,或者是不操作

dp[i]=max(dp[i-1],X[j]*A[i]+Y[j]*B[i])

其中X[j]表示在第j天能买多少A纪念券,Y[j]表示在第j天能买多少B纪念券

可列方程 X[j]*A[j]+Y[j]*B[j]=dp[j]

又因为 X[j]=Rate[j]*Y[j]

所以解出 Y[j]=dp[j]/(B[j]+A[j]*Rate[j])

优化:

dp[i]=X[j]*A[i]+Y[j]*B[i]

Y[j]=dp[i]/B[i] - A[i]/B[i] * x[j]

斜率优化形式,维护上凸壳,最大化截距

点:(X[j],Y[j])

斜率:-A[i]/B[i]

但是 -A[i]/B[i] 不具有单调性

所以不能用单调队列维护斜率

可以用平衡树维护,O(n * logn * logn)

更简单的方法:CDQ分治

假设现在正在计算 dp[l]~dp[r],即solve(l,r)

对于每个j∈[l,r],[1,j-1]都是j的一种决策

令 mid=(l+r)/ 2

我们先计算出 dp[l]~dp[mid],然后用这些去更新 dp[mid+1]~dp[r]

假设我们现在已有了dp[l]~dp[mid]的上凸壳

那么如果保证 mid+1~r的斜率单调

就可以在线性时间内完成 dp[l]~dp[mid] 对 dp[mid+1]~dp[r]的更新

斜率单调可以在归并排序之前的排序预处理中解决

仅剩的问题:如何得到dp[l]~dp[mid] 构成的上凸壳?

在每一层最后归并的时候,我们用线形的时间使l~mid 的点 有序

即横坐标为第一关键字,纵坐标为第二关键字 升序排列,

那么处理完l~mid之后,

会得到l~mid 所有的点 升序排列的结果

对于一些有序的点,用单调栈维护斜率递减即可维护出上凸壳

然后利用这个上凸壳去更新mid+1~r 即可

复杂度为 O(nlogn)

#include<cmath>
#include<cstdio>
#include<algorithm>
#include<iostream> using namespace std; #define N 100001 const double eps=1e-; struct node
{
double A,B,R;
double X,Y;
double K;
int id; bool operator < (node p) const
{
/*if(fabs(X-p.X)>eps) return X<p.X;
return Y<p.Y;*/
return X<p.X;
} }e[N],t[N]; double dp[N],ans; int st[N],top; bool down(int i,int j,int k)
{
return (e[j].X-e[i].X)*(e[k].Y-e[i].Y)-(e[k].X-e[i].X)*(e[j].Y-e[i].Y)<;
} void solve(int l,int r)
{
if(l==r)
{
dp[l]=max(dp[l],dp[l-]);
e[l].Y=dp[l]/(e[l].A*e[l].R+e[l].B);
e[l].X=e[l].Y*e[l].R;
return;
}
int mid=l+r>>;
int opl=l,opr=mid+;
for(int i=l;i<=r;++i)
if(e[i].id<=mid) t[opl++]=e[i];
else t[opr++]=e[i];
for(int i=l;i<=r;++i) e[i]=t[i];
solve(l,mid);
top=;
for(int i=l;i<=mid;++i)
{
while(top> && !down(st[top-],st[top],i)) top--;
st[++top]=i;
}
int now=;
for(int i=mid+;i<=r;++i)
{
while(now<top && (e[st[now]].Y-e[st[now+]].Y)<(e[st[now]].X-e[st[now+]].X)*e[i].K) now++;
dp[e[i].id]=max(dp[e[i].id],e[st[now]].X*e[i].A+e[st[now]].Y*e[i].B);
}
solve(mid+,r);
opl=l; opr=mid+;
for(int i=l;i<=r;++i)
if(opl>mid) t[i]=e[opr++];
else if(opr>r) t[i]=e[opl++];
else if(e[opl]<e[opr]) t[i]=e[opl++];
else t[i]=e[opr++];
for(int i=l;i<=r;++i) e[i]=t[i];
} bool cmp(node p,node q)
{
return p.K>q.K;
} int main()
{
int n;
double m;
scanf("%d%lf",&n,&dp[]);
for(int i=;i<=n;++i)
{
scanf("%lf%lf%lf",&e[i].A,&e[i].B,&e[i].R);
e[i].K=-e[i].A/e[i].B;
e[i].id=i;
}
sort(e+,e+n+,cmp);
solve(,n);
printf("%.3lf",dp[n]);
}

1492: [NOI2007]货币兑换Cash

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 5830  Solved: 2342
[Submit][Status][Discuss]

Description

小Y最近在一家金券交易所工作。该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券(以下
简称B券)。每个持有金券的顾客都有一个自己的帐户。金券的数目可以是一个实数。每天随着市场的起伏波动,
两种金券都有自己当时的价值,即每一单位金券当天可以兑换的人民币数目。我们记录第 K 天中 A券 和 B券 的
价值分别为 AK 和 BK(元/单位金券)。为了方便顾客,金券交易所提供了一种非常方便的交易方式:比例交易法
。比例交易法分为两个方面:(a)卖出金券:顾客提供一个 [0,100] 内的实数 OP 作为卖出比例,其意义为:将
 OP% 的 A券和 OP% 的 B券 以当时的价值兑换为人民币;(b)买入金券:顾客支付 IP 元人民币,交易所将会兑
换给用户总价值为 IP 的金券,并且,满足提供给顾客的A券和B券的比例在第 K 天恰好为 RateK;例如,假定接
下来 3 天内的 Ak、Bk、RateK 的变化分别为:
假定在第一天时,用户手中有 100元 人民币但是没有任何金券。用户可以执行以下的操作:
注意到,同一天内可以进行多次操作。小Y是一个很有经济头脑的员工,通过较长时间的运作和行情测算,他已经
知道了未来N天内的A券和B券的价值以及Rate。他还希望能够计算出来,如果开始时拥有S元钱,那么N天后最多能
够获得多少元钱。

Input

输入第一行两个正整数N、S,分别表示小Y能预知的天数以及初始时拥有的钱数。接下来N行,第K行三个实数AK、B
K、RateK,意义如题目中所述。对于100%的测试数据,满足:0<AK≤10;0<BK≤10;0<RateK≤100;MaxProfit≤1
0^9。
【提示】
1.输入文件可能很大,请采用快速的读入方式。
2.必然存在一种最优的买卖方案满足:
每次买进操作使用完所有的人民币;
每次卖出操作卖出所有的金券。
 

Output

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

Sample Input

3 100
1 1 1
1 2 2
2 2 3

Sample Output

225.000

HINT

bzoj千题计划237:bzoj1492: [NOI2007]货币兑换Cash的更多相关文章

  1. [BZOJ1492] [NOI2007] 货币兑换Cash(cdq分治+斜率优化)

    [BZOJ1492] [NOI2007] 货币兑换Cash(cdq分治+斜率优化) 题面 分析 dp方程推导 显然,必然存在一种最优的买卖方案满足:每次买进操作使用完所有的人民币:每次卖出操作卖出所有 ...

  2. [BZOJ1492][NOI2007]货币兑换Cash(斜率优化+CDQ分治)

    1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 5838  Solved: 2345[Submit][Sta ...

  3. BZOJ1492: [NOI2007]货币兑换Cash 【dp + CDQ分治】

    1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 5391  Solved: 2181 [Submit][S ...

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

    1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 5541  Solved: 2228[Submit][Sta ...

  5. [BZOJ1492] [NOI2007]货币兑换Cash 斜率优化+cdq/平衡树维护凸包

    1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 5907  Solved: 2377[Submit][Sta ...

  6. bzoj千题计划300:bzoj4823: [Cqoi2017]老C的方块

    http://www.lydsy.com/JudgeOnline/problem.php?id=4823 讨厌的形状就是四联通图 且左右各连一个方块 那么破坏所有满足条件的四联通就好了 按上图方式染色 ...

  7. bzoj千题计划196:bzoj4826: [Hnoi2017]影魔

    http://www.lydsy.com/JudgeOnline/problem.php?id=4826 吐槽一下bzoj这道题的排版是真丑... 我还是粘洛谷的题面吧... 提供p1的攻击力:i,j ...

  8. bzoj千题计划280:bzoj4592: [Shoi2015]脑洞治疗仪

    http://www.lydsy.com/JudgeOnline/problem.php?id=4592 注意操作1 先挖再补,就是补的范围可以包含挖的范围 SHOI2015 的题 略水啊(逃) #i ...

  9. bzoj千题计划177:bzoj1858: [Scoi2010]序列操作

    http://www.lydsy.com/JudgeOnline/problem.php?id=1858 2018 自己写的第1题,一遍过 ^_^ 元旦快乐 #include<cstdio> ...

随机推荐

  1. Microsoft Dynamics CRM 增删改子表汇总子表的某个字段到主表的某个字段(通用插件)

    背景 经常有某个汇总子表的数量到主表的总数量,或者汇总子表的总价到主表的总价这种需求. 传统的做法: 1.就是为每个子表实体单独写成一个插件,但是这样不好复用. 2.主表的汇总字段是汇总货币类型,但是 ...

  2. Java+Netty、Vue+Element-UI实现的即时通信应用 leo-im

    之前工作接触了几个开源的IM产品,再加上曾经用Netty实现过几个服务,于是就有了用Netty实现一个IM的想法,于是用业余时间写了一个IM,和喜欢Netty的程序员们分享. 考虑到方便扩展,在服务端 ...

  3. SICP读书笔记 1.1

    SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...

  4. hyperledger-fabirc1.2-ca-server的生产示例

    hyperledger-fabirc1.2-ca-server的生产示例,带TLS 在fabirc-samples/first-network中启动网络,其ca证书是利用crypto的工具生成的,但是 ...

  5. 2013337朱荟潼 Linux第一章读书笔记——Linux内核简介

    一.Unix历史 二.Linux足迹 类Linux系统.非商业化产品.用途广泛 三.操作系统和Linux内核简介 1.操作系统 (1)是指在整个最基本功能系统中负责完成最基本功能和系统管理的部分. ( ...

  6. Window环境下RabbitMQ的安装和配置教程

    一.安装 首先,RabbitMQ基于Erlang语言环境,所以需要先安装Erlang. Erlang下载地址:http://www.erlang.org/downloads 按照安装程序默认安装完成就 ...

  7. 【转载】Activiti delete process definition by key

    http://blog.csdn.net/zwk626542417/article/details/46602419 @RequestMapping(value = "deleteProce ...

  8. 格式化输出Json对象

    1.调用方式: alert(JsonUti.convertToString(jsonObj)); //jsonObj为json对象. 2.格式化输出Json对象方法定义: var JsonUti = ...

  9. 查看django版本的方法

    在cmd输入: python -m django --version django-admin --version

  10. Elk 进阶部署

    虚拟机两台: 192.168.1.42 192.168.1.46 系统环境保持一致: cat /etc/redhat-release uname -a elk准备环境保持一致: elasticsear ...