[BZOJ3963][WF2011]MachineWorks(斜率优化dp+cdq分治)
来源:互联网 发布:雪人翻译软件下载 编辑:程序博客网 时间:2024/05/18 03:54
题目描述
传送门
题解
首先考虑如何暴力dp
肯定是先按照D(i)排序对吧
令f(i)表示在第D(i)天卖掉手里有的机器所能得到的最大收入
那么有一个很显然的dp方程:f(i)=max{f(i-1),max{f(j)-P(j)+G(j)*(D(i)-D(j)-1)+R(j)}}(1<=j<=i-1)
只考虑后半部分,实际上就变成了f(i)=max{f(j)-P(j)+G(j)*(D(i)-D(j)-1)+R(j)}(1<=j<=i-1)
将这个式子变一下形式:f(i)=f(j)-P(j)+G(j)*D(i)-G(j)*D(j)-G(j)+R(j)->令y(j)=f(j)-P(j)-G(j)*D(j)-G(j)+R(j),x(j)=G(j)->f(i)=D(i)*x(j)+y(j)
我们发现这个式子是可以斜率优化的,也就是y(j)=-D(i)*x(j)+f(i);这样就可以看成是一条直线,斜率为-D(i),截距为f(i),现在要选出一个点使截距最大
斜率不满足单调性T_T;不过容易知道这个点一定在一个上凸壳上,那么用splay维护一个上凸壳就行了
用cdq分治的写法更加方便
代码
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>using namespace std;#define N 100005#define LL long longconst double inf=1e18;int Case,n;long double C,D;struct data{ long double d,p,r,g,k,x,y; int id; bool flag;}q[N],a[N],b[N];int stack[N];long double f[N];long double read(){ int x=0;char ch=getchar(); while (ch<'0'||ch>'9') ch=getchar(); while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return (long double)x;}void clear(){ memset(f,0,sizeof(f)); memset(stack,0,sizeof(stack)); for (int i=1;i<=n+1;++i) { q[i].d=q[i].p=q[i].r=q[i].g=0,q[i].id=0,q[i].flag=0,q[i].k=q[i].x=q[i].y=0; a[i].d=a[i].p=a[i].r=a[i].g=0,a[i].id=0,a[i].flag=0,a[i].k=a[i].x=a[i].y=0; b[i].d=b[i].p=b[i].r=b[i].g=0,b[i].id=0,b[i].flag=0,b[i].k=b[i].x=b[i].y=0; }}int cmpd(data a,data b){ return a.d<b.d;}int cmpx(data a,data b){ return a.x<b.x||(a.x==b.x&&a.y>b.y);}int cmpk(data a,data b){ return a.k>b.k;}double getk(data a,data b){ double ax=a.x,ay=a.y,bx=b.x,by=b.y; if (ax==bx) return -inf; return (ay-by)/(ax-bx);}void cdq(int l,int r){ int mid=(l+r)>>1; if (l==r) { f[l]=max(f[l],f[l-1]); if (f[l]>=q[l].p) { q[l].flag=1; q[l].x=q[l].g; q[l].y=f[l]-q[l].p-q[l].g*q[l].d-q[l].g+q[l].r; } return; } cdq(l,mid); int acnt=0,bcnt=0; for (int i=l;i<=mid;++i) a[++acnt]=q[i]; for (int i=mid+1;i<=r;++i) b[++bcnt]=q[i]; sort(a+1,a+acnt+1,cmpx);sort(b+1,b+bcnt+1,cmpk); int top=0; for (int i=1;i<=acnt;++i) if (a[i].flag) { while (top>1&&getk(a[i],a[stack[top]])>=getk(a[stack[top]],a[stack[top-1]])) --top; stack[++top]=i; } int now=1; for (int i=1;i<=bcnt;++i) { while (now<top&&getk(a[stack[now]],a[stack[now+1]])>=b[i].k) ++now; int t=stack[now]; f[b[i].id]=max(f[b[i].id],(LL)a[t].x*b[i].d+(LL)a[t].y); } cdq(mid+1,r);}int main(){ while (~scanf("%d",&n)) { if (!n) break; C=read();D=read(); clear(); for (int i=1;i<=n;++i) { q[i].d=read();q[i].p=read();q[i].r=read();q[i].g=read(); q[i].k=-q[i].d; } sort(q+1,q+n+1,cmpd); q[++n].d=D+1,q[n].p=0,q[n].r=0,q[n].g=0,q[n].k=-q[n].d; for (int i=1;i<=n;++i) q[i].id=i; f[1]=C; cdq(1,n); printf("Case %d: %lld\n",++Case,(long long)f[n]); }}
0 0
- [BZOJ3963][WF2011]MachineWorks(斜率优化dp+cdq分治)
- [BZOJ3963][WF2011][CDQ分治][斜率优化][DP]MachineWorks
- 【BZOJ3963】【ACM-WF2011】MachineWorks(CDQ分治+斜率优化)
- [BZOJ 3963][WF2011]MachineWorks:CDQ分治|DP斜率优化
- bzoj 3963: [WF2011]MachineWorks (DP+CDQ分治)
- bzoj3963 [ WF2011 ] --cdq分治
- [BZOJ2726][SDOI2012]任务安排(斜率优化dp+cdq分治)
- BZOJ 1492 斜率优化dp && cdq分治
- bzoj1492 [ NOI2007 ] --斜率优化DP+cdq分治
- [BZOJ3672][NOI2014]购票-点分治-CDQ分治-斜率优化DP
- CDQ分治与斜率优化DP——学习笔记
- [BZOJ1492][NOI2007][CDQ分治][斜率优化][DP]货币兑换Cash
- 【NOI2007T2】货币兑换-DP斜率优化+CDQ分治
- [BZOJ1492][NOI2007]货币兑换Cash-斜率优化DP-CDQ分治
- bzoj3672 [ NOI2014 ] -- 树上CDQ分治 + 斜率优化DP
- [BZOJ1492][NOI2007]货币兑换Cash(斜率优化dp+cdq分治)
- BZOJ1492:[NOI2007]货币兑换Cash (CDQ分治+斜率优化DP/平衡树维护凸壳)
- BZOJ3672:[Noi2014]购票 (斜率优化DP+二分+(树上CDQ分治/树链剖分))
- CCCC-GPLT L1-037. A除以B 团体程序设计天梯赛
- hdu4294-网络流+最短路
- 4种类型转换操作符 (static_cast const_cast dynamic_cast reinterpret_cast)
- tensorflow-示例2(MNIST集合上进行分类深度卷积网DCNN)
- Leetcode题目按Tag分类
- [BZOJ3963][WF2011]MachineWorks(斜率优化dp+cdq分治)
- 记一次读书感想
- 机房重构Bug
- Java中为什么不推荐使用stop()和suspend()方法
- CPP_Basic_Summary_0.4
- 用qt5.3.2打开ros(机器人操作系統)的界面(CmakeList.txt)
- Win7旗舰版安装tensorflow
- CCCC-GPLT L1-036. A乘以B 团体程序设计天梯赛
- 用php连接数据库