题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1911
解法:斜率DP
//BZOJ 1911
#include <bits/stdc++.h>
using namespace std;
int n, l, r, a, b, c;
int x[1000010];
long long sum[1000010], dp[1000010];
int q[1000010];
inline long long sqr(long long x) {return x*x;}
inline double getxl(int k, int j){
return (double)(dp[j] - dp[k] + a*(sqr(sum[j]) - sqr(sum[k])) + b*(sum[k]-sum[j]))/(double)(2*a*(sum[j]-sum[k]));
}
int main()
{
scanf("%d%d%d%d", &n, &a, &b, &c);
for(int i = 1; i <= n; i++) scanf("%d", &x[i]);
for(int i = 1; i <= n; i++) sum[i] = sum[i-1] + x[i];
for(int i = 1; i <= n; i++){
while(l < r && getxl(q[l], q[l+1]) < sum[i]) l++;
int t = q[l];
dp[i] = dp[t] + a*sqr(sum[i]-sum[t])+b*(sum[i]-sum[t])+c;
while(l < r && getxl(q[r-1], q[r]) > getxl(q[r], i)) r--;
q[++r] = i;
}
printf("%lld\n", dp[n]);
return 0;
}