bzoj1911 [ APIO2010 ] -- 斜率优化

简单的斜率优化。

首先得到DP方程:

f[i]=max(f[j]+a*(sum[i]-sum[j])2+b*(sum[i]-sum[j])+c),j<i

其中sum表示前缀和

设j比k优

f[j]+a*(sum[i]-sum[j])2+b*(sum[i]-sum[j])+c>f[k]+a*(sum[i]-sum[k])2+b*(sum[i]-sum[k])+c

f[j]+a*s[j]2-b*s[j]-(f[k]+a*s[k]2-b*s[k])>2*a*s[i]*(s[j]-s[k])

然后就可以斜率优化了。

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 #define N 1000010
 6 #define ll long long
 7 inline char nc(){
 8     static char buf[100000],*p1=buf,*p2=buf;
 9     if(p1==p2){
10         p2=(p1=buf)+fread(buf,1,100000,stdin);
11         if(p1==p2)return EOF;
12     }
13     return *p1++;
14 }
15 inline void Read(int& x){
16     char c=nc(),b=1;
17     for(;c<'0'||c>'9';c=nc())if(c=='-')b=-1;
18     for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=nc());x*=b;
19 }
20 inline void Read(ll& x){
21     char c=nc(),b=1;
22     for(;c<'0'||c>'9';c=nc())if(c=='-')b=-1;
23     for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=nc());x*=b;
24 }
25 ll y[N],f[N],s[N],k,a,b,c;
26 int i,j,n,m,ch[N],Top,A;
27 int main()
28 {
29     Read(n);Read(a);Read(b);Read(c);
30     for(i=1;i<=n;i++)Read(A),s[i]=s[i-1]+A;
31     for(i=1;i<=n;i++){
32         k=(a<<1)*s[i];
33         while(j<Top&&k*(s[ch[j+1]]-s[ch[j]])<=y[ch[j+1]]-y[ch[j]])j++;
34         f[i]=f[ch[j]]+a*(s[i]-s[ch[j]])*(s[i]-s[ch[j]])+b*(s[i]-s[ch[j]])+c;
35         y[i]=f[i]+a*s[i]*s[i]-b*s[i];
36         while(Top>j&&(y[i]-y[ch[Top-1]])*(s[ch[Top]]-s[ch[Top-1]])>=(y[ch[Top]]-y[ch[Top-1]])*(s[i]-s[ch[Top-1]]))Top--;
37         ch[++Top]=i;
38     }
39     printf("%lld",f[n]);
40     return 0;
41 }
bzoj1911

 

posted @ 2017-03-03 18:55  gjghfd  阅读(172)  评论(0编辑  收藏  举报