首页 > 其他 > 详细

BZOJ - 3156: 防御准备

时间:2018-01-08 16:23:18      阅读:199      评论:0      收藏:0      [点我收藏+]

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: 防御准备

原文:https://www.cnblogs.com/p0ny/p/8242930.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!