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. maven相关基础

    0. 本文主要参考一下良心maven原创文摘: 0.0 maven官网传送门 http://maven.apache.org/ 0.1 maven日常 http://www.cnblogs.com/x ...

  2. 一篇文章详解iOS之AutoResizing、AutoLayout、sizeClass来龙去脉

    前言 iPhone自诞生以来,随着其屏幕尺寸不断的多样化,屏幕适配的技术一直在发展更新.目前,iOS系统版本已经更新到9.3,XCode的最新版本已经是7.3,仅iPhone历史产品的尺寸就已经有4种 ...

  3. 【题解】前k大子段和

    题目描述 Peter喜欢玩数组.NOIP这天,他从Jason手里得到了一个大小为\(n\)的数组. Peter求出了这个数组的所有子段和,并将这\(\frac{n(n+1)}{2}\)个数降序排列,他 ...

  4. [Python web开发] Web框架开发基础 (一)

    Python WEB框架 WSGI,WEB Server Gateway Interface,可以看做是一种底层协议,它规定了服务器程序和应用程序各自实现上面接口.Python的实现称为wsgiref ...

  5. LeetCode刷题(数据库)---- 超过5名学生的课

    题:请列出所有超过或等于5名学生的课. 有一个courses 表 ,有: student (学生) 和 class (课程). 例如,表: +---------+------------+ | stu ...

  6. javascript设计模式系列二-封装

    JavaScript封装: var Book = function (id, name, price) { this.id = id, this.name = name, this.price = p ...

  7. 1004. Counting Leaves(30)—PAT 甲级

    A family hierarchy is usually presented by a pedigree tree. Your job is to count those family member ...

  8. BZOJ 2648: SJY摆棋子(K-D Tree)

    Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 6051  Solved: 2113[Submit][Status][Discuss] Descript ...

  9. MySQL学习之路(一)——初涉MySQL。

    MySQL学习之路(一) 1.1MySQL的概述 MySQL由瑞典MySQL AB公司开发,目前属于Oracle公司. MySQL是一个开源的关系型数据库管理系统. MySQL分为社区版和企业版. 1 ...

  10. Xquery的初步学习(一次Lab作业的总结)

    Task 1: Open countries.xml, compose the following XQueries: 1. Return the area of Mongolia. 2. Retur ...