Description

传送门

Solution

首先,最优情况一定是某一天把所有金券卖出或买入是最优的。

在金券一定的情况下,分散卖一定没有统一在最优的那天卖更优。

然后,我们假定在某一天卖,则在该天前面一定会有一天的全部买入能够使价值最大。

定义ans[i]为第i天能拥有的最大钱数。

则第i天能够有的A金券数为x[i]=ans[i]/(a[i]*rate[i]+b[i])*rate[i],y[i]=ans[i]/(a[i]*rate[i]+b[i])。

ans[i]=max{x[j]*a[i]+y[j]*b[i],ans[i-1]}。(ans[i-1]是假如说该天最优是某一天往后的不买也不卖的情况,因为有时候并不是一定要买卖才是最优的。)

y[j]*b[i]=ans[i]-x[j]*a[i]

y[j]=x[j]*(-a[i]/b[i])+ans[i]/b[i]。

则我们要ans[i]最大,实际上就是在j<i的每一对(x[j],y[j])上画k=-a[i]/b[i]的直线,找最大的截距。这个一看就是凸包的套路。

但是关键是,(x[j],y[j])和直线k的斜率都是没有规律的(即没有递增或递减的情况),直接处理很麻烦。

我们考虑cdq分治。(一天为一个操作,一个操作里包含了该天的信息)

初始情况下,将所有的操作按斜率k来排序。当某一个子问题处理完毕后,将子问题内的所有操作按x坐标排序。这样,当我们分治处理时,[l,mid]内的所有操作都按x排序,[mid+1,r]内的所有操作都按斜率k排序了,当然也必须保证[l,mid]的操作顺序(即第几天)在[mid+1,r]之前。

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const double eps=1e-;
int n; double ans[];
struct node{double a,b,k,rate,x,y;int id;
}w[],q[];
int st[]; double K(int x,int y)
{if (!y) return -1e20;
if (fabs(w[x].x-w[y].x)<eps) return 1e20;
return (w[y].y-w[x].y)/(w[y].x-w[x].x);} bool cmp1(node a,node b){return a.k<b.k;}
bool cmp2(node a,node b)
{return a.x<b.x;}//? void cdq(int l,int r)
{
if (l==r)
{
ans[l]=max(ans[l],ans[l-]);
w[l].y=ans[l]/(w[l].a*w[l].rate+w[l].b);
w[l].x=w[l].y*w[l].rate;
return;
}
int mid=(l+r)/,js0=l,js1=mid+,tp=;
for (int i=l;i<=r;i++)
if (w[i].id<=mid) q[js0++]=w[i];else q[js1++]=w[i];
for (int i=l;i<=r;i++) w[i]=q[i]; cdq(l,mid);
for (int i=l;i<=mid;i++)
{
while (tp>&&K(st[tp],st[tp-])<K(i,st[tp-])+eps) tp--;
st[++tp]=i;
} int j=;
for (int i=mid+;i<=r;i++)
{
while (tp>&&w[i].k>K(st[tp],st[tp-])-eps) tp--;
ans[w[i].id]=max(ans[w[i].id],w[st[tp]].x*w[i].a+w[st[tp]].y*w[i].b);
} cdq(mid+,r);js0=l;js1=mid+;
merge(w+l,w+mid+,w+mid+,w+r+,q+l,cmp2);
for (int i=l;i<=r;i++) w[i]=q[i];
}
int main()
{
scanf("%d%lf",&n,&ans[]);
for (int i=;i<=n;i++)
{
scanf("%lf%lf%lf",&w[i].a,&w[i].b,&w[i].rate);w[i].id=i;
w[i].k=-1.0*w[i].a/w[i].b;
}
sort(w+,w+n+,cmp1);
cdq(,n);
printf("%.3f",ans[n]);
}

[BZOJ1492][NOI2007]cash-[cdq分治]的更多相关文章

  1. [bzoj1492][NOI2007]Cash[CDQ分治;dp;斜率优化]

    首先,设f[x]表示x天能获得的A券最大值,有动规方程: $f[i]=max\{f[j]*A[i]+f[j]*B[i]/R[j]\}*R[i]/(R[i]*A[i]+B[i])$, 设 $j<k ...

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

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

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

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

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

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

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

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

  6. [NOI2007]货币兑换 cdq分治,斜率优化

    [NOI2007]货币兑换 LG传送门 妥妥的\(n \log n\)cdq做法. 这题用cdq分治也可以\(n \log n\)但是在洛谷上竟然比一些优秀的splay跑得慢真是见了鬼了看来还是人丑常 ...

  7. BZOJ 1492 货币兑换 Cash CDQ分治

    这题n2算法就是一个维护上凸包的过程. 也可以用CDQ分治做. 我的CDQ分治做法和网上的不太一样,用左边的点建立一个凸包,右边的点在上面二分. 好处是思路清晰,避免了凸包的插入删除,坏处是多了一个l ...

  8. BZOJ1492: [NOI2007]货币兑换Cash(CDQ分治,斜率优化动态规划)

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

  9. 【BZOJ1492】【Luogu P4027】 [NOI2007]货币兑换 CDQ分治,平衡树,动态凸包

    斜率在转移顺序下不满足单调性的斜率优化\(DP\),用动态凸包来维护.送命题. 简化版题意:每次在凸包上插入一个点,以及求一条斜率为\(K\)的直线与当前凸包的交点.思路简单实现困难. \(P.s\) ...

  10. bzoj1492 斜率优化|cdq分治

    #include <stdio.h> #include <bitset> #include <string.h> #include <stack> #i ...

随机推荐

  1. IntelliJ IDEA 下载和激活

    IntelliJ IDEA 下载地址: https://www.jetbrains.com/idea/download/#section=windows 激活码获取地址:http://idea.lan ...

  2. Linux环境下GNU, GCC, G++编译器

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u012823258/article/details/36890125 一.GNU GNU是" ...

  3. [转]使用QT开发GoogleMap瓦片显示和下载工具

    第一节 之前做项目的时候经常遇到需要大量地图背景数据,然后没有数据被逼着去Google上下载瓦片数据在拼接成整张影像的工作,其实遥感影像晚上有很多可以下载到的,但是大部分是作为研究用的,作为GIS的背 ...

  4. JDK(一)JDK集合框架

    JDK中的集合框架分为两大类:Collection和Map.Collection以一组Object的形式保存元素,Map以Key-Value对的形式保存元素. 上图列出的类并不完整,只列举了平时比较常 ...

  5. PAT——1053. 住房空置率

    在不打扰居民的前提下,统计住房空置率的一种方法是根据每户用电量的连续变化规律进行判断.判断方法如下: 在观察期内,若存在超过一半的日子用电量低于某给定的阈值e,则该住房为“可能空置”: 若观察期超过某 ...

  6. vlc源码分析(一) RTSP会话流程

    可以先了解一下RTSP/RTP/RTCP的概念与区别:RTP与RTCP协议介绍(转载). 在调试vlc-android时,熟悉了RTSP的会话流程.C表示RTSP客户端,S表示RTSP服务端: 第一步 ...

  7. 转 Grand Central Dispatch 基础教程:Part 1/2 -swift

    本文转载,原文地址:http://www.cocoachina.com/ios/20150609/12072.html 原文 Grand Central Dispatch Tutorail for S ...

  8. JDBC——连接数据库的代码

    第一步:在SCR下创建一个file,写好数据库的相关信息. #oracle数据库 driver=oracle.jdbc.driver.OracleDriver jdbcUrl=jdbc:oracle: ...

  9. luogu11月月赛T3咕咕咕(组合数学)

    题目描述 小 F 是一个能鸽善鹉的同学,他经常把事情拖到最后一天才去做,导致他的某些日子总是非常匆忙. 比如,时间回溯到了 2018 年 11 月 3 日.小 F 望着自己的任务清单: 看 iG 夺冠 ...

  10. 【2016 ICPC亚洲区域赛北京站 E】What a Ridiculous Election(BFS预处理)

    Description In country Light Tower, a presidential election is going on. There are two candidates,   ...