# cychester

## 题解

$F_i = \max( F_j + a \times (S_i - S_j) ^2 + b \times (S_i - S_j ) + c)$ 数组S为前缀和

## 代码

 1 #include<cstring>
2 #include<algorithm>
3 #include<cstdio>
5 #define rep(i,a,b) for(int i = (a); i <= (b); ++i)
6 #define per(i,a,b) for(int i = (a); i >= (b); --i)
7 #define ll long long
8 using namespace std;
9
10 const int N = 1e6 + 1e5;
11
12 ll f[N], a, b, c, s[N], q[N], sum[N], n;
13
15     int X = 0, p = 1; char c = getchar();
16     for(; c > '9' || c < '0'; c = getchar()) if( c == '-') p = -1;
17     for(; c >= '0' && c <= '9'; c = getchar()) X = X * 10 + c - '0';
18     return X * p;
19 }
20
21 double caly(int A) {
22     return f[A] + a * sum[A] * sum[A] - b * sum[A];
23 }
24
25 double calk(int A, int B) {
26     double ax = sum[A], bx = sum[B], ay = caly(A), by = caly(B);
27     return (by - ay) / (bx - ax);
28 }
29
30
31 int main()
32 {
33     n = rd;
34     a = rd; b = rd; c = rd;
35     rep(i, 1, n) s[i] = rd, sum[i] = sum[i - 1] + s[i];
36     int l = 1, r = 1;
37     rep(i, 1, n) {
38         while(l < r && calk(q[l], q[l + 1]) >= 2 * a * sum[i]) l++;
39         ll x = sum[i] - sum[q[l]];
40         f[i] = f[q[l]] + a * x * x + b * x + c;
41         while(l < r && calk(q[r - 1], q[r]) <= calk(q[r], i)) r--;
42         q[++r] = i;
43     }
44     printf("%lld\n", f[n]);
45 }
46 
View Code

posted on 2018-08-19 19:30  cychester  阅读(108)  评论(0编辑  收藏  举报