BZOJ - 3156: 防御准备

Posted p0ny

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ - 3156: 防御准备相关的知识,希望对你有一定的参考价值。

3156: 防御准备

可以很容易地写出$dp$方程。

记$dp_i$为在$i$处放一个守卫塔,从$j$处转移,$j+i...i-1$放木偶。$dp_1=a_1$

为了处理$n$处放木偶的情况,咱一直处理到$n+1$。

$dp_i = min\{dp_j + \sum_{k=j+1}^{i-1}(k-j)\}+a_i$

$dp_i=dp_j+\frac{(i-j)(i-j+1)}{2}+a_i$

如果$j$比$k$优,

$2dp_j+(i-j-1)(i-j)<2dp_k+(i-k-1)(i-k)$

不妨设$j>k$,

$\frac{(2dp_j+j^2+j)-(2dp_k+k^2+k)}{j-k}<2i$

让斜率递减就行。

 1 #include<cstdio>
 2 #include<deque>
 3 #include<iostream>
 4 using namespace std;
 5 inline char nc() {
 6     static char b[1<<16],*s=b,*t=b;
 7     return s==t&&(t=(s=b)+fread(b,1,1<<16,stdin),s==t)?-1:*s++;
 8 }
 9 inline void read(int &x) {
10     char b = nc(); x = 0;
11     for (; !isdigit(b); b = nc());
12     for (; isdigit(b); b = nc()) x = x * 10 + b - 0;
13 }
14 typedef double db;
15 typedef long long ll;
16 const int N = 1000005;
17 int n, a[N];
18 ll dp[N];
19 inline db Y(int i) {
20     return 2.0 * dp[i] + db(i) * i + i;
21 }
22 inline db slope(int l, int r) {
23     return (Y(r) - Y(l)) / (r - l);
24 }
25 int main() {
26     read(n); deque < int > q(1, 1);
27     for (int i = n; i; --i) read(a[i]);
28     dp[1] = a[1];
29     for (int i = 2; i <= n+1; ++i) {
30         while (q.size() > 1 && slope(q[0], q[1]) < 2 * i) q.pop_front();
31         int j = q.front(); dp[i] = dp[j] + (i - j) * (i - j - 1ll) / 2 + a[i];
32         while (q.size() > 1 && slope(q[q.size()-2], q.back()) > slope(q.back(), i)) q.pop_back();
33         q.push_back(i);
34     } printf("%lld\n", dp[n+1]);
35     return 0;
36 }

 

以上是关于BZOJ - 3156: 防御准备的主要内容,如果未能解决你的问题,请参考以下文章

bzoj3156 防御准备

bzoj 3156: 防御准备

BZOJ3156防御准备 斜率优化

bzoj3156防御准备 斜率优化dp

BZOJ - 3156: 防御准备

BZOJ 3156 防御准备