bzoj 1492: [NOI2007]货币兑换Cash
2016-03-13 06:04
351 查看
#include<cstdio> #include<iostream> #include<algorithm> #include<cmath> #define eps 1e-9 using namespace std; #define M 100008 double f[M]; struct data { double k,a,b,rate,x,y; int id; }q[M],t[M]; int zhan[M],n; bool cmp(data a1,data a2) { return a1.k>a2.k; } double dp(int a1,int a2) { if(!a2) return -1e20; if(fabs(q[a1].x-q[a2].x)<eps) return 1e20; return (q[a1].y-q[a2].y)/(q[a1].x-q[a2].x); } void fen(int l,int r) { if(l==r) { f[l]=max(f[l],f[l-1]); q[l].y=f[l]/(q[l].a*q[l].rate+q[l].b); q[l].x=q[l].rate*q[l].y; return; } int mid=(l+r)>>1,l1=l,l2=mid+1; for(int i=l;i<=r;i++) if(q[i].id<=mid) t[l1++]=q[i]; else t[l2++]=q[i]; for(int i=l;i<=r;i++) q[i]=t[i]; fen(l,mid); int t2=0; for(int i=l;i<=mid;i++) { for(;t2>1&&dp(zhan[t2-1],zhan[t2])<dp(zhan[t2],i)+eps;t2--); zhan[++t2]=i; } t2++; zhan[t2]=0; int t1=1; for(int i=mid+1;i<=r;i++) { for(;t1<t2&&dp(zhan[t1],zhan[t1+1])+eps>q[i].k;) t1++; f[q[i].id]=max(f[q[i].id],q[zhan[t1]].x*q[i].a+q[zhan[t1]].y*q[i].b); } fen(mid+1,r); l1=l; l2=mid+1; for(int i=l;i<=r;i++) if(((q[l1].x<q[l2].x||(fabs(q[l1].x-q[l2].x)<eps&&q[l1].y<q[l2].y))||l2>r)&&l1<=mid) t[i]=q[l1++]; else t[i]=q[l2++]; for(int i=l;i<=r;i++) q[i]=t[i]; return; } int main() { scanf("%d%lf",&n,&f[0]); for(int i=1;i<=n;i++) { scanf("%lf%lf%lf",&q[i].a,&q[i].b,&q[i].rate); q[i].id=i; q[i].k=-q[i].a/q[i].b; } sort(q+1,q+n+1,cmp); fen(1,n); printf("%.3lf",f ); return 0; }
这是个斜率优化dp,用cdq去做。f[i]代表到i天时的最大获利,q[i].x,q[i].y表示在第i天全部买股票能买多少
相关文章推荐
- bzoj 1491: [NOI2007]社交网络
- 71.双向最短路径:聚会
- bzoj 1483: [HNOI2009]梦幻布丁
- 71.双向最短路径:聚会
- 71.双向最短路径:聚会
- [leetcode] 245. Shortest Word Distance III 解题报告
- bzoj 1433: [ZJOI2009]假期的宿舍
- bzoj 1432: [ZJOI2009]Function
- bzoj 1415: [Noi2005]聪聪和可可
- bzoj 1412: [ZJOI2009]狼和羊的故事
- Palindrome 系列
- 谷歌人机大战与新时代的来临
- 工厂模式之小结与区别(6)
- 抽象工厂模式(5)
- 抽象工厂模式(4)
- leetcode@ [116/117] Populating Next Right Pointers in Each Node I & II (Tree, BFS)
- !getApplicationContext()和Activity.this区别
- 【Android】20.4 录音
- MarkDown的简介
- 【Android】20.3 拍照和视频录制