3156: 防御准备(斜率优化)

链接

思路

  斜率优化。

   f[i] 表示i点建检查点的花费。

  f[i] = f[j] + i*(i-j-1)-(s[i-1]-s[j]) + a[i],从j转移,s为前缀和。

代码

 1 #include<cstdio>
 2 #include<iostream>
 3 
 4 using namespace std;
 5 
 6 typedef long long LL;
 7 
 8 const int N = 1000100;
 9 LL s[N],f[N],a[N];
10 int q[N],L,R;
11 
12 inline int read() {
13     int x = 0,f = 1;char ch = getchar();
14     for (; !isdigit(ch); ch=getchar()) if(ch=='-') f=-1;
15     for (; isdigit(ch); ch=getchar()) x = x*10+ch-'0';
16     return x * f;
17 }
18 double slope(int i,int j) {
19     return double(f[i]+s[i]-f[j]-s[j])/double(i-j);
20 }
21 int main() {
22     int n = read();
23     for (int t,i=1; i<=n; ++i) {
24         t = read();
25         a[i] = (LL)t;
26         s[i] = s[i-1] + (LL)i;
27     }
28     L = R = 1;
29     q[1] = 0;
30     for (int i=1; i<=n; ++i) {
31         while (L<R && slope(q[L],q[L+1]) < 1.0*i) L++;
32         int j = q[L];
33         f[i] = f[j] + 1ll*i*(i-j-1) - (s[i-1]-s[j]) + a[i]; // i*(j-1)需要变成longlong 
34         while (L<R && slope(q[R-1],q[R]) > slope(q[R],i)) R--;
35         q[++R] = i;
36     }
37     cout << f[n];
38     return 0;
39 }

 

posted @ 2018-04-29 18:11  MJT12044  阅读(182)  评论(0编辑  收藏  举报