【BZOJ】1492: [NOI2007]货币兑换Cash
【题意】初始资金s,有两种金券A和B,第i天,买入时将投入的资金购买比例为rate[i]的两种股票,卖出时将持有的一定比例的两种股票卖出,第i天股票价格为A[i],B[i],求最大获利。n<=100000。
【算法】动态规划+斜率优化(CDQ分治)
【题解】为了最大获利,每次交易一定是全部买进和全部卖出。
令s[i]表示前i天的最大获利,f[i]表示第i天能购买的最多A股数,g[i]=f[i]/rate[i]表示第i天能购买的最多B股数。
s[i]=max{ s[i-1] , f[j]*A[i]+g[j]*B[i] },j<i。
g[i]=s[i]/(A[i]*rate[i]+B[i])
f[i]=g[i]*rate[i]
对于决策j和k,假设f[j]<f[k],当k优于j时有:
f[j]*A[i]+g[j]*B[i]<f[k]*A[i]+g[k]*B[i]
移向得(g[j]-g[k])/(f[j]-f[k])>-A[i]/B[i],令k[i]=-A[i]/B[i],所以:
对于满足f[j]<f[k]的决策j和k,满足(g[j]-g[k])/(f[j]-f[k])>k[i]时决策k优于决策j。
然后用CDQ分治维护动态上凸包,按阶段分治,左子区间按x[]排序构造凸包,右子区间按k[]排序顺序决策。
具体过程见:CDQ分治优化动态规划
复杂度O(n log n)。
#include<cstdio>
#include<cstring>
#include<cctype>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=;
const double eps=1e-,inf=;
double s[maxn];
int n,st[maxn];
struct cyc{int id;double A,B,r,k,x,y;}a[maxn],b[maxn];
bool cmp(cyc a,cyc b){return a.k>b.k;}
double k(int A,int B){
if(fabs(a[A].x-a[B].x)<eps){if(a[B].y<a[A].y)return -inf;else return inf;}
return (a[A].y-a[B].y)/(a[A].x-a[B].x);
}
void CDQ(int l,int r){
if(l==r){
s[l]=max(s[l],s[l-]);
a[l].y=s[l]/(a[l].A*a[l].r+a[l].B);
a[l].x=a[l].y*a[l].r;
return;
}
int mid=(l+r)>>;
int x1=l-,x2=mid;
for(int i=l;i<=r;i++)if(a[i].id<=mid)b[++x1]=a[i];else b[++x2]=a[i];
for(int i=l;i<=r;i++)a[i]=b[i];
CDQ(l,mid);
int top=;
for(int i=l;i<=mid;i++){
while(top>&&k(st[top],i)>k(st[top-],st[top]))top--;
st[++top]=i;
}
int x=;
for(int i=mid+;i<=r;i++){
while(x<top&&k(st[x],st[x+])>a[i].k)x++;
s[a[i].id]=max(s[a[i].id],a[st[x]].x*a[i].A+a[st[x]].y*a[i].B);
}
CDQ(mid+,r);
x1=l,x2=mid+;
for(int i=l;i<=r;i++){
if(x1>mid)b[i]=a[x2++];else
if(x2>r)b[i]=a[x1++];else
if(a[x1].x<a[x2].x)b[i]=a[x1++];else b[i]=a[x2++];
}
for(int i=l;i<=r;i++)a[i]=b[i];
}
int main(){
scanf("%d%lf",&n,&s[]);
for(int i=;i<=n;i++){
a[i].id=i;
scanf("%lf%lf%lf",&a[i].A,&a[i].B,&a[i].r);
a[i].k=-a[i].A/a[i].B;
}
sort(a+,a+n+,cmp);
CDQ(,n);
printf("%.3lf",s[n]);
return ;
}
【BZOJ】1492: [NOI2007]货币兑换Cash的更多相关文章
- BZOJ 1492: [NOI2007]货币兑换Cash( dp + 平衡树 )
dp(i) = max(dp(i-1), x[j]*a[i]+y[j]*b[i]), 0<j<i. x, y表示某天拥有的最多钱去买金券, 金券a和金券b的数量. 然后就很明显了...平衡 ...
- ●BZOJ 1492 [NOI2007]货币兑换Cash
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1492 题解: 斜率优化DP,CDQ分治 定义$DP[i]$为第i天结束后的最大收益. 由于题 ...
- bzoj 1492 [NOI2007]货币兑换Cash(斜率dp+cdq分治)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1492 [题意] 有AB两种货币,每天可以可以付IPi元,买到A券和B券,且A:B= ...
- 斜率优化(CDQ分治,Splay平衡树):BZOJ 1492: [NOI2007]货币兑换Cash
Description Input 第一行两个正整数N.S,分别表示小Y 能预知的天数以及初始时拥有的钱数. 接下来N 行,第K 行三个实数AK.BK.RateK,意义如题目中所述 Output 只有 ...
- BZOJ 1492: [NOI2007]货币兑换Cash [CDQ分治 斜率优化DP]
传送门 题意:不想写... 扔链接就跑 好吧我回来了 首先发现每次兑换一定是全部兑换,因为你兑换说明有利可图,是为了后面的某一天两种卷的汇率差别明显而兑换 那么一定拿全利啊,一定比多天的组合好 $f[ ...
- bzoj 1492: [NOI2007]货币兑换Cash
Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券(以下 简称B券).每个持有金券的顾客都有一个自己的帐户.金券的数目可以是一个 ...
- BZOJ 1492 [NOI2007]货币兑换Cash:斜率优化dp + cdq分治
传送门 题意 初始时你有 $ s $ 元,接下来有 $ n $ 天. 在第 $ i $ 天,A券的价值为 $ A[i] $ ,B券的价值为 $ B[i] $ . 在第 $ i $ 天,你可以进行两种操 ...
- bzoj 1492: [NOI2007]货币兑换Cash【贪心+斜率优化dp+cdq】
参考:http://www.cnblogs.com/lidaxin/p/5240220.html 虽然splay会方便很多,但是懒得写,于是写了cdq 首先要想到贪心的思路,因为如果在某天买入是能得到 ...
- BZOJ 1492 [NOI2007]货币兑换Cash (CDQ分治/splay 维护凸包)
题目大意:太长了略 splay调了两天一直WA弃疗了 首先,我们可以猜一个贪心,如果买/卖,就一定都买/卖掉,否则不买/卖 反正货币的行情都是已知的,没有任何风险,所以肯定要选择最最最优的方案了 容易 ...
- BZOJ 1492: [NOI2007]货币兑换Cash 斜率优化 + splay动态维护凸包
Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券(以下 简称B券).每个持有金券的顾客都有一个自己的帐户.金券的数目可以是一个 ...
随机推荐
- lintcode-384-最长无重复字符的子串
384-最长无重复字符的子串 给定一个字符串,请找出其中无重复字符的最长子字符串. 样例 例如,在"abcabcbb"中,其无重复字符的最长子字符串是"abc" ...
- ltnmp 3.0 发布,PHP 开发环境一键安装包
PHP 开发环境一键安装包, 有个叫lnmp.这个ltnmp看起来更新比较多,开发比较频繁,包括的组件更多. 安装和使用教程:http://www.moqifei.com/ltnmp 标记一下.
- 3dContactPointAnnotationTool开发日志(三三)
添加背景图片后发现Runtime Transform Gizmo无法选中物体了: 于是改了一下EditorObjectSelection.cs中的WereAnyUIElementsHovere ...
- 【Leetcode】50. Pow(x, n)
Implement pow(x, n). Example 1: Input: 2.00000, 10 Output: 1024.00000 Example 2: Input: 2.10000, 3 O ...
- yum 安装php环境
centos下安装php环境 | 浏览:3831 | 更新:2014-11-04 17:01 1 2 3 分步阅读 在网上看了很多,很多都不能用,所以就把能用的实践下,过程记录下,方便自己和网友以后查 ...
- PHP与类有关的几个魔术方法
与类有关的其他魔术方法 序列化与反序列化技术 含义: 序列化: 就是将一个变量所代表的“内存”数据,转换为“字符串”形式并持久保存在硬盘上的一种做法. 反序列化: 就是将序列化之后保存在硬盘上的“字符 ...
- shell脚本中调用其他脚本的三种方法
方法一:使用 . #. ./sub.sh 方法二:使用 source #source ./sub.sh 方法三:使用 sh #sh ./sub.sh 注意: 1.两个点之间,要有空 ...
- UVA12545_Bits Equalizer
题目意思很简单,给你两个串,第一个串为0,1或者?,第二个串为0,1, 每次你可以对第一个串进行三种操作,1.0变为1:2.?变为0或者1:3.交换任意两个数的位置. 现在问你能否把第一个串变为第一个 ...
- ios基础动画、关键帧动画、动画组、转场动画等
概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌.在这里你可以看到iOS中如何使用图层精简非交互式绘图,如何通过核心动画创建基础动画.关键帧动画 ...
- cdq分治学习
看了stdcall大佬的博客 传送门: http://www.cnblogs.com/mlystdcall/p/6219421.html 感觉cdq分治似乎很多时候都要用到归并的思想