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. SQL脚本修改表结构

    SQL脚本修改表结构 新建表:create table [表名]([自动编号字段] int IDENTITY (1,1) PRIMARY KEY ,[字段1] nVarChar(50) default ...

  2. CentOS7中安装VMwareTools

    本例中为在Linux(以CentOS 7为例)安装VMware Tools. 1.首先启动CentOS 7,在VMware中点击上方“VM”,点击“Install VMware Tools...”(如 ...

  3. selenium + python自动化测试unittest框架学习(一)selenium原理及应用

    unittest框架的学习得益于虫师的<selenium+python自动化实践>这一书,该书讲得很详细,大家可以去看下,我也只学到一点点用于工作中,闲暇时记录下自己所学才能更加印象深刻. ...

  4. PyTorch Softmax

    PyTorch provides 2 kinds of Softmax class. The one is applying softmax along a certain dimension. Th ...

  5. HDU 1050(楼道搬桌子问题)(不是贪心解法,思路很新颖)

    Moving Tables Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...

  6. 鼠标不能用怎么办 USB OPTICAL MOUSE

    刚买的新鼠标,一般鼠标插上去自动安装驱动,然后就可以正常使用了. 如果遇到下面这种情况:"usb optical mouse 找不到驱动程序" 插上以后死活都没作用,然后开始下载一 ...

  7. css 尾巴

    用border制作三角形 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...

  8. CCF认证201803-1 跳一跳

    import java.util.Scanner; public class Jump { public static void main(String[] args) { Scanner sc = ...

  9. sharepoint搜索配置问题

    配置sharepoint 爬网内容源,如我们有4台前端服务器,集群域名为eds.jd.com,2台用于爬网前端服务器,集群域名为crawl.eds.jd.com 配置内容源的时候,将地址配为: 结果一 ...

  10. Vue2 轮播图组件 slide组件

    Vue2原生始轮播图组件,支持宽度自适应.高度设置.轮播时间设置.左右箭头按钮控制,圆点按钮切换,以及箭头.圆点按钮是否显示. <v-carousel :slideData="slid ...