【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-422-最后一个单词的长度
422-最后一个单词的长度 给定一个字符串, 包含大小写字母.空格' ',请返回其最后一个单词的长度. 如果不存在最后一个单词,请返回 0 . 注意事项 一个单词的界定是,由字母组成,但不包含任何的空 ...
- NULL指针引起的一个linux内核漏洞
NULL指针一般都是应用于有效性检测的,其实这里面有一个约定俗成的规则,就是说无效指针并不一定是 NULL,只是为了简单起见,规则约定只要指针无效了就将之设置为NULL,结果就是NULL这个指针被用来 ...
- js & enter
js & enter keycode function (e) { if (e.which === 13 || e.keyCode === 13) { //code to execute he ...
- 【EF】EF Code-First数据迁移
Code-First数据迁移 首先要通过NuGet将EF升级至最新版本. 新建MVC 4项目MvcMigrationDemo 添加数据模型 Person 和 Department,定义如下: usi ...
- 对Spark2.2.0文档的学习1-Cluster Mode Overview
Cluster Mode Overview Link:http://spark.apache.org/docs/2.2.0/cluster-overview.html Spark应用(Applicat ...
- 利用JavaFX访问MySQL数据库
1. 创建数据库表 create table Course( courseId char(5), subjectId char(4) not null, courseNumber integer, t ...
- 题解 P1781 【宇宙总统】
小金羊发现用的方法和python大佬们的方法还是不一样... (大概是我太弱了qAq) emmm... (Mode:Python 3)Code: a=int(input()) #几个数 L=list( ...
- 导出ORACLE表结构到SQL语句(含CLOB)
转自:http://blog.itpub.net/84738/viewspace-442854/ 先用exp导出空表 exp username/password rows=n file=expor ...
- [CQOI2011]动态逆序对 CDQ分治
洛谷上有2道相同的题目(基本是完全相同的,输入输出格式略有不同) ---题面--- ---题面--- CDQ分治 首先由于删除是很不好处理的,所以我们把删除改为插入,然后输出的时候倒着输出即可 首先这 ...
- 【BZOJ5418】【NOI2018】屠龙勇士(数论,exgcd)
[NOI2018]屠龙勇士(数论,exgcd) 题面 洛谷 题解 考场上半个小时就会做了,一个小时就写完了.. 然后发现没过样例,结果大力调发现中间值爆\(longlong\)了,然后就没管了.. 然 ...