bzoj3437 小P的牧场
斜率优化dp
代码
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 typedef long long ll; 5 const int N = 1001010; 6 int n,i,j,l,r,q[N]; 7 ll f[N],v[N],s[N],a[N]; 8 ll calc(int x,int i) 9 { 10 return f[x]+a[i]+v[x+1]-v[i]-(n-i)*(s[x+1]-s[i]); 11 } 12 double A(int x,int y) 13 { 14 return f[x]+v[x+1]-f[y]-v[y+1]; 15 } 16 double B(int x,int y) 17 { 18 return s[x+1]-s[y+1]; 19 } 20 int main() 21 { 22 scanf("%d",&n); 23 for (i=1;i<=n;i++) 24 scanf("%lld",&a[i]); 25 for (i=1;i<=n;i++) 26 scanf("%lld",&s[i]); 27 for (j=n;j>=1;j--) 28 { 29 v[j]=v[j+1]+s[j]*(n-j); 30 s[j]+=s[j+1]; 31 } 32 l=1;r=1; 33 for (i=1;i<=n;i++) 34 { 35 while ((l<r)&&(A(q[l],q[l+1])>=B(q[l],q[l+1])*(n-i))) l++; 36 f[i]=calc(q[l],i); 37 while ((l<r)&&(A(q[r],i)*B(q[r-1],q[r])>A(q[r-1],q[r])*B(q[r],i))) r--; 38 r++;q[r]=i; 39 } 40 printf("%lld\n",f[n]); 41 } 42 //f[x]+v[x+1]-f[y]-v[y+1]>(s[x+1]-s[y+1])*(n-i) 43 //A(y,z)/B(y,z)>A(x,y)/B(x,y)