Description
![](http://www.lydsy.com/JudgeOnline/images/1911_1.jpg)
Input
![](http://www.lydsy.com/JudgeOnline/images/1911_2.jpg)
Output
![](http://www.lydsy.com/JudgeOnline/images/1911_3.jpg)
Sample Input
4
-1 10 -20
2 2 3 4
-1 10 -20
2 2 3 4
Sample Output
9
HINT
Source
一道斜率优化的裸题,几乎就是玩具装箱的模型。。
仿照玩具装箱的公式化简的方式最后得到斜率式如下:
(dp[k]-dp[j]+a*s[k]*s[k]-b*s[k]-a*s[j]*s[j]+b*s[j])/
((s[k]-s[j])*2*a)<=s[i]
代码如下:
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iostream>
using
namespace
std;
typedef
long
long
LL;
const
int
maxn=1000002;
int
n,a,b,c,q[maxn];
LL dp[maxn],s[maxn],
tm
[maxn];
double
slop(
int
k,
int
j){
return
(
double
)(dp[k]-dp[j]+a*s[k]*s[k]-b*s[k]-a*s[j]*s[j]+b*s[j])/(
double
)((s[k]-s[j])*2*a);
}
void
DP(){
int
h=1,t=1;q[t]=0;
for
(
int
i=1;i<=n;++i){
while
(h<t&&slop(q[h],q[h+1])<=s[i])++h;
dp[i]=dp[q[h]]+a*(s[i]-s[q[h]])*(s[i]-s[q[h]])+b*(s[i]-s[q[h]])+c;
while
(h<t&&slop(q[t],i)<slop(q[t-1],q[t]))--t;
q[++t]=i;
}
}
int
main(){
scanf
(
"%d"
,&n);
scanf
(
"%d%d%d"
,&a,&b,&c);
for
(
int
i=1;i<=n;++i){
scanf
(
"%lld"
,&
tm
[i]);
s[i]=s[i-1]+
tm
[i];
}
DP();
printf
(
"%lld\n"
,dp[n]);
return
0;
}