BZOJ_1492_[NOI2007]货币兑换Cash_CDQ分治+斜率优化
BZOJ_1492_[NOI2007]货币兑换Cash_CDQ分治+斜率优化
Description
.png)
.png)
Input
Output
只有一个实数MaxProfit,表示第N天的操作结束时能够获得的最大的金钱数目。答案保留3位小数。
Sample Input
1 1 1
1 2 2
2 2 3
Sample Output
HINT
.png)
首先贪心的想,每天的操作只有三种可能,什么也不干,全部买入和全部卖出。
设x[i]为第i天能获得A卷的数量,y[i]为第i天能获得B卷的数量。
y[i]=f[i]/(rate[i]*A[i]+B[i]),x[i]=y[i]*rate[i]。
那么f[i]=max(f[i-1],x[j]*A[i]+y[j]*B[i]),其中我们需要找到一个已经确定F值得j来转移这个过程。
F[i]=X[j]*A[i]+Y[j]*B[i]
F[i]/A[i]=Y[j]*(B[i]/A[i])+X[j]。
把Y[j]当做斜率。那么我们会发现不仅Y[j]不单调,每次切的横坐标(B[i]/A[i])也不单调。
这时候我们使用CDQ分治。
本题的思想:对左边进行处理,处理左边对右边的影响(F的转移),再对右边进行处理。
先按(B[i]/A[i])排序,然后每步再按斜率归并上去。
也就是说我们到了一个局面,满足左边的斜率单调,右边每次切的横坐标单调。
这个就很好办了,对左边单调栈求凸包,然后维护一个指针扫一遍凸包。
正确性:所有能更新F[i]的F[j]在更新F[i]之前都已经更新完毕了,同时F[i]被1~i-1中的每个F[j]都更新到了。
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
typedef double f2;
#define N 100050
#define eps 1e-6
f2 xx[N],yy[N],f[N],A[N],B[N],rate[N],K[N],pos[N];
int n,t[N],tmp[N],S[N];
#define Y(i,j) (K[j]*pos[i]+xx[j])
bool cmp(int x,int y) {return pos[x]<pos[y];}
bool judge(int p1,int p2,int p3) {
return (yy[p2]-yy[p3])*(xx[p1]-xx[p2])<=(yy[p1]-yy[p2])*(xx[p2]-xx[p3]);
}
void solve(int l,int r) {
if(l==r) {
f[l]=max(f[l],f[l-1]);
yy[l]=f[l]/(rate[l]*A[l]+B[l]);
xx[l]=yy[l]*rate[l];
K[l]=yy[l];
return ;
}
int mid=(l+r)>>1;
int i,j=l,k=mid+1;
for(i=l;i<=r;i++) {
if(t[i]<=mid) tmp[j++]=t[i];
else tmp[k++]=t[i];
}
for(i=l;i<=r;i++) t[i]=tmp[i];
solve(l,mid);
int top=0;
for(i=l;i<=mid;i++) {
while(top>1&&judge(S[top-1],S[top],t[i])) top--;
S[++top]=t[i];
}
for(j=1,i=mid+1;i<=r;i++) {
while(j<top&&Y(t[i],S[j+1])>=Y(t[i],S[j])) j++;
f[t[i]]=max(f[t[i]],Y(t[i],S[j])*A[t[i]]);
}
solve(mid+1,r);
i=j=l,k=mid+1;
while(j<=mid&&k<=r) {
if(K[t[j]]<=K[t[k]]) tmp[i++]=t[j++];
else tmp[i++]=t[k++];
}
while(j<=mid) tmp[i++]=t[j++];
while(k<=r) tmp[i++]=t[k++];
for(i=l;i<=r;i++) t[i]=tmp[i];
}
int main() {
scanf("%d%lf",&n,&f[0]);
int i,j;
for(i=1;i<=n;i++) {
scanf("%lf%lf%lf",&A[i],&B[i],&rate[i]);
t[i]=i; pos[i]=B[i]/A[i];
}
sort(t+1,t+n+1,cmp);
solve(1,n);
printf("%.3f\n",f[n]);
}
BZOJ_1492_[NOI2007]货币兑换Cash_CDQ分治+斜率优化的更多相关文章
- BZOJ 1492 [NOI2007]货币兑换Cash:斜率优化dp + cdq分治
传送门 题意 初始时你有 $ s $ 元,接下来有 $ n $ 天. 在第 $ i $ 天,A券的价值为 $ A[i] $ ,B券的价值为 $ B[i] $ . 在第 $ i $ 天,你可以进行两种操 ...
- BZOJ1492:[NOI2007]货币兑换 (CDQ分治+斜率优化DP | splay动态维护凸包)
BZOJ1492:[NOI2007]货币兑换 题目传送门 [问题描述] 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和B纪念券(以下简称B券).每个持有金券的 ...
- [BZOJ1492] [NOI2007] 货币兑换Cash(cdq分治+斜率优化)
[BZOJ1492] [NOI2007] 货币兑换Cash(cdq分治+斜率优化) 题面 分析 dp方程推导 显然,必然存在一种最优的买卖方案满足:每次买进操作使用完所有的人民币:每次卖出操作卖出所有 ...
- UOJ#7. 【NOI2014】购票 点分治 斜率优化 凸包 二分
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ7.html 题解 这题是Unknown的弱化版. 如果这个问题出在序列上,那么显然可以CDQ分治 + 斜率 ...
- BZOJ3672 [Noi2014]购票 【点分治 + 斜率优化】
题目链接 BZOJ3672 题解 如果暂时不管\(l[i]\)的限制,并假使这是一条链 设\(f[i]\)表示\(i\)节点的最优答案,我们容易得到\(dp\)方程 \[f[i] = min\{f[j ...
- 【uoj#244】[UER #7]短路 CDQ分治+斜率优化dp
题目描述 给出 $(2n+1)\times (2n+1)$ 个点,点 $(i,j)$ 的权值为 $a[max(|i-n-1|,|j-n-1|)]$ ,找一条从 $(1,1)$ 走到 $(2n+1,2n ...
- BZOJ_3672_ [Noi2014]购票_CDQ分治+斜率优化
BZOJ_3672_ [Noi2014]购票_CDQ分治+斜率优化 Description 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参 ...
- bzoj1492[NOI2007]货币兑换Cash cdq分治+斜率优化dp
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 5541 Solved: 2228[Submit][Sta ...
- [NOI2007]货币兑换 cdq分治,斜率优化
[NOI2007]货币兑换 LG传送门 妥妥的\(n \log n\)cdq做法. 这题用cdq分治也可以\(n \log n\)但是在洛谷上竟然比一些优秀的splay跑得慢真是见了鬼了看来还是人丑常 ...
随机推荐
- LeetCode OJ--Search in Rotated Sorted Array II
http://oj.leetcode.com/problems/search-in-rotated-sorted-array-ii/ 如果在数组中有重复的元素,则不一定说必定前面或者后面的一半是有序的 ...
- 使用css绘制六边形
用css绘制六边形需要使用到三个容器,分别用于绘制六边形的三个部分,如下图所示: 接下来,就是代码了: CSS: ;;border-top: 30px solid #6c6;border-left: ...
- springBoot 跨域处理
首先喝水不忘挖井人,博客参考:https://www.cnblogs.com/nananana/p/8492185.html 方式一:新增一个configration类 或 在Application中 ...
- [vxlan] 二 什么是VXLAN
VXLAN是一种mac in UDP的技术.简单讲就是传统的二层帧被封装到了UDP的package中.通过UDP的IP网络发送到目的地然后再解封装. VXLAN 跟VLAN对比,最重要的一个概念就是V ...
- printf行缓冲区的分析总结
最近在客户那调试串口的时候,read串口然后printf打印,单字符printf,发现没有输出,后来想起来printf这些标准输入输出函数也是属于标准C库glibc的, 这里就要区分一下标准库函数和系 ...
- centos 複製時顯示進度的指令 pv
Pipe Viewer 的简称pv:意思是通过管道显示数据处理进度的信息.这些信息包括已经耗费的时间,完成的百分比(通过进度条显示),当前的速度,全部传输的数据,以及估计剩余的时间. yum inst ...
- 第二种BitBand操作的方式 - 让IDE来帮忙算地址
要使用Bitband来訪问外设,一定要得出相应的映射地址.人工计算肯定是不靠谱的,并且也没人想这么干.因此能够通过Excel,拉个列表来计算.想想,这也是一个不错的招数.可是后来想想,还是嫌麻烦,毕竟 ...
- JAVASE学习笔记:第八章 经常使用类Util工具包之日期类、数字类
一.Date类 日期类 所在java.Util工具包 before(Date when) 測试此日期是否在指定日期之前. getDay() 获取星期的某一天 getDate( ...
- 删除moduleCache下文件解决预编译头文件相关的编译错误
之前有在代码全部正确的情况下,遇到过下面的编译错误: fatal error: file '.....h' has been modified since the precompiled header ...
- mac上pydev
转自:http://m.blog.csdn.net/blog/yangfu132/23689823 本来网上有教程,但是往往又一些不周到的地方,让人走了不少弯路. 使用 PyDev 进行调试 第一步: ...