[hdu3507] Print Article
传送门
今天的斜率优化dp第二题,被自己坑了好长时间
一开始dp方程都错了,还过了样例。。。
正题,斜率方程其实很好推,就是细节比较坑,其它没什么难的,我不说思路了。
\[slope(j,k)=\frac {f_j-f_k+s_j^2-s_k^2} {s_j-s_k}
\]
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline int read(){
int x=0;char ch=' ';int f=1;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
int n,m;
ll c[500011],s[500011],f[500011],q[500011];
inline ll up(int j,int k){
return (ll)(f[k]-f[j]+s[k]*s[k]-s[j]*s[j]);
}
inline ll down(int j,int k){
return (ll)(s[k]-s[j]);
}
int main(){
while(scanf("%d %d",&n,&m)==2){
memset(f,0,sizeof(f));
memset(q,0,sizeof(q));
memset(s,0,sizeof(s));
for(int i=1;i<=n;i++){
c[i]=read();
s[i]=s[i-1]+c[i];
}
int l=1,r=0;
q[++r]=0;
for(int i=1;i<=n;i++){
while(l<r&&up(q[l],q[l+1])<=2*s[i]*down(q[l],q[l+1]))l++;
f[i]=f[q[l]]+(s[i]-s[q[l]])*(s[i]-s[q[l]])+m;
while(l<r&&up(q[r],i)*down(q[r-1],q[r])<=up(q[r-1],q[r])*down(q[r],i))r--;
q[++r]=i;
}
printf("%lld\n",f[n]);
}
return 0;
}