APIO 2010 特别行动队 | 斜率优化DP
标签:表示 etc sof tar nbsp www target ret 序列
luogu 3628
si表示序列的前缀和
f(i)表示将序列的前i个划分若干段的最大价值
f(i)= max{f(j)+a∗(si−sj)2+b∗(si−sj)+c},1≤j<i
= max{−2a*sj*si+f(j)+a*sj*sj−b*sj}+a*si*si+b*si+c,1≤j<i
1 #include 2 #include string>
3
4 typedef long long ll;
5
6 ll a, b, c;
7
8 ll read() {
9 ll x = 0, f = 1;
10 char c = getchar();
11 while (!isdigit(c)) {
12 if (c == ‘-‘) f = -1;
13 c = getchar();
14 }
15 while (isdigit(c)) {
16 x = (x 3) + (x 1) + (c ^ 48);
17 c = getchar();
18 }
19 return x * f;
20 }
21
22 ll s[1000005], f[1000005]; int Q[1000005];
23
24 ll K(int j) {
25 return -2 * a * s[j];
26 }
27
28 ll B(int j) {
29 return f[j] + a * s[j] * s[j] - b * s[j];
30 }
31
32 ll Y(int i, int j) {
33 return K(j) * s[i] + B(j);
34 }
35
36 bool cover(int i, int j, int k) {
37 ll y1 = (K(i) - K(k)) * (B(j) - B(i));
38 ll y2 = (K(i) - K(j)) * (B(k) - B(i));
39 return y1 y2;
40 }
41
42 int main() {
43 int n = read(); a = read(), b = read(), c = read();
44 for (int i = 1; i i) {
45 ll x = read(); s[i] = s[i - 1] + x;
46 }
47 int l = 0, r = 0;
48 for (int i = 1; i i) {
49 while (l 1])) ++ l;
50 f[i] = Y(i, Q[l]) + a * s[i] * s[i] + b * s[i] + c;
51 while (l 1])) -- r;
52 Q[++r] = i;
53 }
54 printf("%lld\n", f[n]);
55 }
APIO 2010 特别行动队 | 斜率优化DP
标签:表示 etc sof tar nbsp www target ret 序列
原文地址:https://www.cnblogs.com/milky-w/p/8541609.html
评论