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 }