# bzoj1911 [Apio2010]特别行动队

【题解】

1. 假设j<k，j没有k优

f[j]+a(s[i+1]-s[j])^2 + b(s[i+1]-s[j]) + c <= f[k] + a(s[i+1]-s[k])^2 + b(s[i+1]-s[k]) + c

2ax[i+1](s[i]-s[j])+bx[i+1] <= 2ax[i+1](s[i]-s[k])+bx[i+1]

2. 推斜率式

((f[j]+as[j]^2-bs[j])-(f[k]+as[k]^2-bs[k]))/(2a(s[j]-s[k])) <= s[i]

# include <stdio.h>
# include <string.h>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 1e6 + 10;
const int mod = 1e9+7;

# define RG register
# define ST static

int n, A, B, C, a[M];
int q[M], head, tail;
ll f[M], s[M];

inline ld slop(int j, int k) {
return (ld)((s[j]*s[j]*A-s[j]*B+f[j])-(s[k]*s[k]*A-s[k]*B+f[k]))/(ld)((s[j]-s[k])*2*A);
}

int main() {
scanf("%d%d%d%d", &n, &A, &B, &C);
for (int i=1; i<=n; ++i) {
scanf("%d", a+i);
s[i] = s[i-1] + a[i];
}

head = 1, tail = 1; q[tail] = 0;
for (int i=1; i<=n; ++i) {
while(head < tail && slop(q[head], q[head+1]) <= (ld)s[i]) ++head;
int t = q[head];
f[i] = f[t] + (s[i]-s[t])*(s[i]-s[t])*A + (s[i]-s[t])*B + C;
while(head < tail && slop(q[tail-1], q[tail]) > slop(q[tail], i)) --tail;
q[++tail] = i;
}
printf("%lld\n", f[n]);
return 0;
}
View Code

posted @ 2017-04-27 21:16  Galaxies  阅读(124)  评论(0编辑  收藏  举报