bzoj千题计划237:bzoj1492: [NOI2007]货币兑换Cash
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
.png)
.png)
Input
Output
只有一个实数MaxProfit,表示第N天的操作结束时能够获得的最大的金钱数目。答案保留3位小数。
Sample Input
1 1 1
1 2 2
2 2 3
Sample Output
HINT
.png)
bzoj千题计划237: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   【dp + CDQ分治】
		
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MB Submit: 5391 Solved: 2181 [Submit][S ...
 - bzoj1492[NOI2007]货币兑换Cash cdq分治+斜率优化dp
		
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 5541 Solved: 2228[Submit][Sta ...
 - [BZOJ1492] [NOI2007]货币兑换Cash  斜率优化+cdq/平衡树维护凸包
		
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 5907 Solved: 2377[Submit][Sta ...
 - bzoj千题计划300:bzoj4823: [Cqoi2017]老C的方块
		
http://www.lydsy.com/JudgeOnline/problem.php?id=4823 讨厌的形状就是四联通图 且左右各连一个方块 那么破坏所有满足条件的四联通就好了 按上图方式染色 ...
 - bzoj千题计划196:bzoj4826: [Hnoi2017]影魔
		
http://www.lydsy.com/JudgeOnline/problem.php?id=4826 吐槽一下bzoj这道题的排版是真丑... 我还是粘洛谷的题面吧... 提供p1的攻击力:i,j ...
 - bzoj千题计划280:bzoj4592: [Shoi2015]脑洞治疗仪
		
http://www.lydsy.com/JudgeOnline/problem.php?id=4592 注意操作1 先挖再补,就是补的范围可以包含挖的范围 SHOI2015 的题 略水啊(逃) #i ...
 - bzoj千题计划177:bzoj1858: [Scoi2010]序列操作
		
http://www.lydsy.com/JudgeOnline/problem.php?id=1858 2018 自己写的第1题,一遍过 ^_^ 元旦快乐 #include<cstdio> ...
 
随机推荐
- Unity关于方法事件生命周期官方文档
			
http://docs.unity3d.com/Manual/ExecutionOrder.html 一.组件运行的基本顺序 下图中创建类的顺序为A,B,C,A1,二运行的结果为A1,B,C,A. 可 ...
 - java后台面试知识点总结
			
本文主要记录在准备面试过程中遇到的一些基本知识点(持续更新) 一.Java基础知识 1.抽象类和接口的区别 接口和抽象类中都可以定义变量,但是接口中定义的必须是公共的.静态的.Final的,抽象类中的 ...
 - Linux内核设计与实现(chapter1/2)
			
Linux内核简介 Unix从一个失败的多用户操作系统Multics中衍生来的. Unix强大的原因: 简洁 几乎所有的东西都被当做文件来对待,可以通过相同的系统调用接口来进行调用. 因为它是由c语言 ...
 - 第一周:通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
			
姓名:吕松鸿 学号:20135229 ( *原创作品转载请注明出处*) ( 学习课程:<Linux内核分析>MOOC课程http://mooc.study.163.com/course/U ...
 - 英语学习APP
			
第一部分 调研, 评测 下载并使用,描述最简单直观的个人第一次上手体验. 界面高大上,看起来很美观,是个不错的英语学习软件.我很喜欢. 2.按照<构建之法>13.1节描述的 bug 定义, ...
 - 自定义SQL语句
			
在用@query写了sql语句后,返回的结果集不能自动转换为自定义的对象. 百度有一篇博客,解决方案是直接在sql语句里实例化对象,我用了,但是语法错误,又谷歌了下,sql语句里是不能这样写的,这是h ...
 - 11th  回顾5个问题
			
当初提出的5个问题: 1.书中说很多非常成功的软件都是赢在用户体验,后面的第12章也专门提到了用户体验,说软件开发时可以使用5W1H的方法来判断用户的体验,而需求分析需要获取用户需求,进行用户调研,那 ...
 - HDU 2088 Box of Bricks
			
http://acm.hdu.edu.cn/showproblem.php?pid=2088 Problem Description Little Bob likes playing with his ...
 - CMS垃圾收集器与G1收集器
			
1.CMS收集器 CMS收集器是一种以获取最短回收停顿时间为目标的收集器.基于“标记-清除”算法实现,它的运作过程如下: 1)初始标记 2)并发标记 3)重新标记 4)并发清除 初始标记.从新标记这两 ...
 - [转帖]Vim编辑器使用方法详解
			
Vim编辑器使用方法详解 程序员小新人学习 2018-12-16 12:26:23 转载于https://www.cnblogs.com/libaoliang/articles/6961676.htm ...