BZOJ 1911 [Apio2010]特别行动队 (斜率优化DP)

斜率优化DP裸题,DP方程很简单就不给了

优化一下,整理式子成y=kx+b的形式

发现x单调递增,斜率k单调递减,用一个队列维护凸包就行啦

f[i]和b成正比,而f[i]期望最大值,所以维护上凸包

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 #define il inline
 5 #define ll long long
 6 #define N 1001000
 7 using namespace std;
 8 //re
 9 int n;
10 ll A,B,C;
11 int que[N];
12 ll f[N],d[N],sum[N];
13 int gc()
14 {
15     int rett=0,fh=1;char c=getchar();
16     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
17     while(c>='0'&&c<='9'){rett=(rett<<3)+(rett<<1)+c-'0';c=getchar();}
18     return rett*fh;
19 }
20 il ll yy(int i){return f[i]+A*sum[i]*sum[i]-B*sum[i]+C;}
21 il ll xx(int i){return sum[i];}
22 
23 int main()
24 {
25     n=gc(),A=gc(),B=gc(),C=gc();
26     for(int i=1;i<=n;i++) d[i]=gc();
27     for(int i=1;i<=n;i++) sum[i]=sum[i-1]+d[i];
28     int hd=1,tl=1;
29     for(int i=1;i<=n;i++)
30     {
31         while(hd+1<=tl&&yy(que[hd])-(ll)2*A*sum[i]*xx(que[hd]) <= yy(que[hd+1])-(ll)2*A*sum[i]*xx(que[hd+1]))
32             hd++;
33         f[i]=yy(que[hd])-(ll)2*A*sum[i]*xx(que[hd])+A*sum[i]*sum[i]+B*sum[i];
34         while(hd+1<=tl&& (yy(i)-yy(que[tl]))*(xx(que[tl])-xx(que[tl-1])) >= (yy(que[tl])-yy(que[tl-1]))*(xx(i)-xx(que[tl])))
35             tl--;
36         que[++tl]=i;
37     }
38     printf("%lld\n",f[n]);
39     return 0;
40 }

 

posted @ 2018-09-24 22:32  guapisolo  阅读(98)  评论(0编辑  收藏  举报