Description
Input
Output
Sample Input
- -
Sample Output
HINT
Solution
斜率优化动态规划
首先易得出这样的一个朴素状态转移方程
f[i]=max{f[j]+cal(sum[i]-sum[j])}
其中j<i,且cal(x)=a*x*x+b*x+c
那么设转移方程中的式子为V
若i<j,且V(j)>V(i)
那么,f[j]-f[i]+a*sum[j]^2-a*sum[i]^2+b*(sum[i]-sum[j])>2*a*(sum[j]-sum[i])*sum[i]
就可以斜率优化了
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int N=;
typedef long long ll;
inline ll sq(ll x){
return x*x;
}
inline int read(){
int x=,c=getchar(),f=;
for(;c<||c>;c=getchar())
if(!(c^))
f=-;
for(;c>&&c<;c=getchar())
x=(x<<)+(x<<)+c-;
return x*f;
}
int n,a,b,c,q[N];
ll sum[N],f[N];
inline double slope(int x,int y){
return (double)(f[y]-f[x]+a*(sq(sum[y])-sq(sum[x]))+b*(sum[x]-sum[y]))/(double)(*a*(sum[y]-sum[x]));
}
int main(){
n=read(),a=read(),b=read(),c=read();
for(int i=;i<=n;i++)
sum[i]=(ll)read()+sum[i-];
int l=,r=;
for(int i=;i<=n;i++){
while(l<r&&slope(q[l],q[l+])<sum[i])l++;
int t=q[l];
f[i]=f[t]+a*sq(sum[i]-sum[t])+b*(sum[i]-sum[t])+c;
while(l<r&&slope(q[r-],q[r])>slope(q[r],i))r--;
q[++r]=i;
}
printf("%lld\n",f[n]);
return ;
}
orz hzwer