[BZOJ3963][WF2011]MachineWorks(斜率优化dp+cdq分治)
2018-01-14 20:20
483 查看
题目:
我是超链接题解:
这题目有点眼熟啊。。。莫不是货币兑换?那根据套路来一波dp,f[i]表示到第D[i]天卖掉所有机器得到的最多金钱,显然f[0]=c
f[i]=max(f[i−1],f[j]−P[j]+(D[i]−D[j]−1)∗G[j]+R[j])
列完方程我们可以知道,之所以这样设计是因为读入的D[i]影响的是前一群机器而不是这一个(因为还没开始用。)
f[i]=f[j]−P[j]+(D[i]−D[j]−1)∗G[j]+R[j]
f[j]−P[j]−(D[j]+1)∗G[j]+R[j]=−D[i]∗G[j]+f[i]
那就是斜率固定-D[i],使截距f[i]最大,把之前的看做一个点(G[j],f[j]-P[j]-(D[j]+1)*G[j]+R[j]),那就维护一个上凸壳用cdq分治求解
注意比较的时候不能光比较x,还要把y比上
INF要设的大一点= =
代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define LL long long using namespace std; const double INF=1e18; //// const int N=100005; struct hh{int id;LL x,y,d,p,r,g,k;}Q ,jl ; int stack ,n; LL f ,d,c; double getk(hh a,hh b) { if (a.x==b.x) return -INF; return (double)(a.y-b.y)/(double)(a.x-b.x); } int cmpx(hh a,hh b){return a.x<b.x||(a.x==b.x&&a.y>b.y);} //// void merge(int l,int r) { int mid=(l+r)>>1,t1=l,t2=mid+1; for (int i=l;i<=r;i++) if ((t1<=mid && cmpx(Q[t1],Q[t2])) || t2>r) jl[i]=Q[t1++]; else jl[i]=Q[t2++]; for (int i=l;i<=r;i++) Q[i]=jl[i]; } void cdq(int l,int r) { if (l==r) { f[l]=max(f[l],f[l-1]); Q[l].x=Q[l].g; if (f[l]>=Q[l].p) Q[l].y=f[l]-Q[l].p-(LL)(Q[l].d+1)*Q[l].g+Q[l].r; else Q[l].y=-INF; return; } int mid=(l+r)>>1,t1=l,t2=mid+1; for (int i=l;i<=r;i++) if (Q[i].id<=mid) jl[t1++]=Q[i]; else jl[t2++]=Q[i]; for (int i=l;i<=r;i++) Q[i]=jl[i]; cdq(l,mid); int top=0; for (int i=l;i<=mid;i++) if (Q[i].y!=-INF) { while (top>1 && getk(Q[i],Q[stack[top]])>=getk(Q[stack[top-1]],Q[stack[top]])) top--; stack[++top]=i; } for (int i=mid+1;i<=r;i++) { while (top>1 && getk(Q[stack[top]],Q[stack[top-1]])<jl[i].k) top--; int j=stack[top]; f[jl[i].id]=max(f[jl[i].id],Q[j].y-(LL)jl[i].k*Q[j].x); } cdq(mid+1,r); merge(l,r); } int cmpk(hh a,hh b){return a.k<b.k;} int cmpd(hh a,hh b){return a.d<b.d;} int main() { int id=0;scanf("%d%lld%lld",&n,&c,&d); while (n&&c&&d) { memset(f,0,sizeof(f));f[1]=c; for (int i=1;i<=n;i++) scanf("%lld%lld%lld%lld",&Q[i].d,&Q[i].p,&Q[i].r,&Q[i].g); sort(Q+1,Q+n+1,cmpd); for (int i=1;i<=n;i++) Q[i].id=i,Q[i].k=-Q[i].d; Q[++n].d=d+1; Q .k=-Q .d; Q .id=n; sort(Q+1,Q+n+1,cmpk); cdq(1,n); printf("Case %d: %lld\n",++id,f ); scanf("%d%lld%lld",&n,&c,&d); } }
相关文章推荐
- [BZOJ3963][WF2011]MachineWorks(斜率优化dp+cdq分治)
- BZOJ 3963: [WF2011]MachineWorks [CDQ分治 斜率优化DP]
- [BZOJ 3963][WF2011]MachineWorks:CDQ分治|DP斜率优化
- [BZOJ3963][WF2011][CDQ分治][斜率优化][DP]MachineWorks
- 【BZOJ3963】【ACM-WF2011】MachineWorks(CDQ分治+斜率优化)
- BZOJ_3963_[WF2011]MachineWorks_斜率优化+CDQ分治
- 【BZOJ3963】[WF2011]MachineWorks cdq分治+斜率优化
- bzoj3963[WF2011]MachineWorks cdq分治+斜率优化dp
- bzoj 3963: [WF2011]MachineWorks (DP+CDQ分治)
- bzoj3963 [WF2011]MachineWorks(斜率优化 & splay维护动态凸包)
- 【BZOJ】3963: [WF2011]MachineWorks
- ●BZOJ 3963 [WF2011]MachineWorks
- 3963: [WF2011]MachineWorks
- bzoj1492 [NOI2007]货币兑换Cash(斜率优化DP+cdq分治)
- [BZOJ2726][SDOI2012]任务安排(斜率优化dp+cdq分治)
- [BZOJ4709][JSOI2011]柠檬(斜率优化DP)
- [BZOJ1492][NOI2007]货币兑换Cash(斜率优化dp+cdq分治)
- BZOJ 4073 Wf2014 Buffed Buffet 斜率优化
- 【BZOJ3693】【WF2011】MachineWorks
- bzoj1492 [ NOI2007 ] --斜率优化DP+cdq分治