BZOJ1492:[NOI2007]货币兑换——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1492
(题目描述太长了不粘贴了……)
………………………………………………………
我
是自己做的
抄开心
的
……………………………………………………………
所以……emm,简单的dp就是:
f(i)=max(a[i]*x[j]+b[i]*y[j])
其中x和y表示在第i 天,用最多的钱能够换成的A券和B券。
完后……这怎么斜率优化啊……如果把x和y看做点来斜率优化的话它们也没有单调性啊。
推荐一个博客,可以在这里看推导式子(其实是我懒):http://blog.csdn.net/lych_cys/article/details/50674962
平衡树固然可以解决问题,但是CDQ分治在这种问题上显得更加睿智。
我们完全可以对其变成一维排a/b,二维CDQ一下它们出现时间t,三维求f。把每个点看做询问和添加操作即可。
剩下的就是单调队列基础操作了。
(题解瞎编完了hhh)
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
typedef double dl;
const int N=1e5+;
struct node{
dl x,y;
inline bool operator <(const node &b)const{
return x<b.x||x==b.x&&y<b.y;
}
}p[N],que[N];
int n,t[N],tmp[N];
dl f[N],a[N],b[N],rate[N],ans;
inline bool cmp(int x,int y){
return a[x]*b[y]<a[y]*b[x];
}
inline bool slope(node k,node j,node i){
return (j.x-i.x)*(k.y-i.y)-(j.y-i.y)*(k.x-i.x)<=;
}
inline dl suan(node j,int i){
return j.x*a[i]+j.y*b[i];
}
void cdq(int l,int r){
if(l==r){
f[l]=max(f[l],f[l-]);
ans=max(ans,f[l]);
p[l].y=f[l]/(a[l]*rate[l]+b[l]);
p[l].x=p[l].y*rate[l];
return;
}
int mid=(l+r)>>,idx1=l,idx2=mid+,ql=,qr=;
for(int i=l;i<=r;i++){
if(t[i]<=mid)tmp[idx1++]=t[i];
else tmp[idx2++]=t[i];
}
for(int i=l;i<=r;i++)t[i]=tmp[i];
cdq(l,mid);
for(int i=l;i<=mid;i++){
while(qr>&&slope(que[qr-],que[qr],p[i]))qr--;
que[++qr]=p[i];
}
for(int i=mid+;i<=r;i++){
int j=t[i];
while(ql<qr&&suan(que[ql],j)<=suan(que[ql+],j))ql++;
f[j]=max(f[j],suan(que[ql],j));
}
cdq(mid+,r);
if(l==&&r==n)return;
ql=l,idx1=l,idx2=mid+;
while(ql<=r){
if(idx2>r||idx1<=mid&&p[idx1]<p[idx2])que[ql++]=p[idx1++];
else que[ql++]=p[idx2++];
}
for(int i=l;i<=r;i++)p[i]=que[i];
return;
}
int main(){
scanf("%d%lf",&n,&f[]);
for(int i=;i<=n;i++){
scanf("%lf%lf%lf",&a[i],&b[i],&rate[i]);
t[i]=i;
}
sort(t+,t+n+,cmp);
cdq(,n);
printf("%.3lf\n",ans);
return ;
}
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
BZOJ1492:[NOI2007]货币兑换——题解的更多相关文章
- [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 ...
- bzoj千题计划237:bzoj1492: [NOI2007]货币兑换Cash
http://www.lydsy.com/JudgeOnline/problem.php?id=1492 dp[i] 表示 第i天卖完的最大收益 朴素的dp: 枚举从哪一天买来的在第i天卖掉,或者是不 ...
- [BZOJ1492] [NOI2007]货币兑换Cash 斜率优化+cdq/平衡树维护凸包
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 5907 Solved: 2377[Submit][Sta ...
- BZOJ1492 [NOI2007]货币兑换
Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券(以下 简称B券).每个持有金券的顾客都有一个自己的帐户.金券的数目可以是一个 ...
- BZOJ1492: [NOI2007]货币兑换Cash
设$x_j$,$y_j$为第$j$天能买的A,B券数量,$f_i$为第$i$天的最大收益.$f_i=\max_{1\le j<i}a_ix_j+b_iy_j$,最大化$f_i$即找一个点$(x_ ...
- Bzoj1492: [NOI2007]货币兑换Cash(不单调的斜率优化)
题面 传送门 Sol 题目都说了 必然存在一种最优的买卖方案满足: 每次买进操作使用完所有的人民币: 每次卖出操作卖出所有的金券. 设\(f[i]\)表示第\(i\)天可以有的最大钱数 枚举\(j&l ...
随机推荐
- nginx 路由配置
nginx中location对url匹配: 语法:location [=|~|~*|^~] /uri/ { … } 当匹配中符合条件的location,则执行内部指令:如果使用正则表达式,必须使用~* ...
- mysql c 获取error_code
#include <stdio.h> #include <mysql.h> int main(int argc, char **argv) { MYSQL *con = mys ...
- PS 抠图和添加背景图
1.打开需要抠的图--然后使用套索类工具,魔棒类工具,钢笔类工具均可选择需要扣的图片范围任何在Delete(如果抠反了可以进行反选Ctrl +shift+I) 2.然后把任一一张背景图直接拖到PS里面 ...
- pyhon文件操作典型代码实现(非常经典!)
1. 编写一个程序,统计当前目录下每个文件类型的文件数,程序实现如图: 实现代码: import os all_files = os.listdir(os.chdir("D:\\" ...
- CSP201703-1:分蛋糕
引言:CSP(http://www.cspro.org/lead/application/ccf/login.jsp)是由中国计算机学会(CCF)发起的"计算机职业资格认证"考试, ...
- 标注点(Labeled Point)
标注点LabeledPoint是一种带有标签(Label/Response)的本地向量,它可以是稠密或者是稀疏的.在MLlib中,标注点在监督学习算法中被使用.由于标签是用双精度浮点型来存储的,故标注 ...
- 正式放弃Edge,重新拥抱Chrome
从Edge还叫斯巴达的时候我就开始用了,本来对浏览器的要求也没多高,能够打开多个选项卡,稳定,支持最新的规范就好了. 但是Edge真的是越来越让我失望了,卡死问题越来越多,崩溃越来越频繁,我也快奔溃了 ...
- c字符指针与字符数组的区别
1.定义 char *pchar; //定义了指针,没赋值之前不能使用.如果:printf("*pchar:%c\n",*pchar); 出现段错误Segmentation fa ...
- fp-growth树创建代码及详细注释
事务集过滤重排: #FP树节点结构 class treeNode: def __init__(self,nameValue,numOccur,parentNode): self.name=nameVa ...
- 常用算法Java实现之快速排序
快速排序和冒泡排序相似,都是通过多次比较和交换来实现排序. 具体流程如下: 1.首先设定一个分界值,通过分界值将数组分成左右两部分,将大于等于分界值的数据交换集中到右侧数组,将小于分界值的数据交换集中 ...