BZOJ 1911: [Apio2010]特别行动队 (斜率优化DP)

BZOJ1911

1911: [Apio2010]特别行动队

Time Limit: 4 Sec Memory Limit: 64 MB Submit: 2695 Solved: 1209 [Submit][Status][Discuss]

Description

Input

Output

Sample Input

4 -1 10 -20 2 2 3 4

Sample Output

9

HINT

一道比较水的斜率优化的题目。 进行DP,然后把方程写出来就可以了。 mark下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/* ***************

Author :kuangbin

Created Time :2015/5/5 21:49:21

File Name :F:\ACM\2015ACM\专题练习\斜率DP\BZOJ1911.cpp

************************************************ */

#include <stdio.h>

#include <string.h>

#include <iostream>

#include <algorithm>

#include <vector>

#include <queue>

#include <set>

#include <map>

#include <string>

#include <math.h>

#include <stdlib.h>

#include <time.h>

using namespace std;

const int MAXN = 1000010;

long long sum[MAXN];

long long X[MAXN],Y[MAXN];

long long dp[MAXN];

long long det(int k,int j,int i){

long long x1 = X[j] - X[k];

long long y1 = Y[j] - Y[k];

long long x2 = X[i] - X[k];

long long y2 = Y[i] - Y[k];

return x1*y2 - x2*y1;

}

int que[MAXN];

int main()

{

//freopen("in.txt","r",stdin);

//freopen("out.txt","w",stdout);

int a,b,c;

int n;

while(scanf("%d",&n) == 1){

scanf("%d%d%d",&a,&b,&c);

sum[0] = 0;

for(int i = 1;i <= n;i++){

int tmp;

scanf("%d",&tmp);

sum[i] = sum[i-1] + tmp;

}

dp[0] = 0;

X[0] = 0;

Y[0] = 0;

int st,ed;

st = ed = 0;

que[ed++] = 0;

for(int i = 1;i <= n;i++){

int k = 2*a*sum[i];

while(st+1 < ed && Y[que[st]]-k*X[que[st]] <= Y[que[st+1]]-k*X[que[st+1]])st++;

dp[i] = a*sum[i]*sum[i] + b*sum[i] + c + Y[que[st]] - k*X[que[st]];

X[i] = sum[i];

Y[i] = dp[i] + a*sum[i]*sum[i] - b*sum[i];

while(st+1 < ed && det(que\[ed-2\],que\[ed-1\],i) >= 0)ed--;

que[ed++] = i;

}

printf("%lld\n",dp[n]);

}



return 0;

}
------ 本文结束------
  • 本文作者: kuangbin
  • 本文链接: 600.html
  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
0%