bzoj3437 小P的牧场（斜率优化dp）

3437: 小P的牧场

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 2025  Solved: 1110
[Submit][Status][Discuss]

4
2424
3142

Sample Output

9

1<=n<=1000000, 0 < a i ,bi < = 10000

Source

$f[i]=f[j]-(j-i)*s[i]+a[i]$

$f[j]=s[i]*j+f[i]+i*s[i]+a[i]$

$y=f[j]$

$k=s[i]$

$x=j$

$b=f[i]+i*s[i]+a[i]$

$k,x$均单调

#include<iostream>
#include<cstdio>
#include<cstring>
#define rint register int
using namespace std;
typedef long long ll;
#define N 1000005
ll a[N],b[N],s[N],f[N],ans;
int n,L,R,h[N];
inline ll X(int i){return i;}
inline ll Y(int i){return f[i];}
inline ll KK(ll xa,ll ya,ll xb,ll yb){return ya*xb-yb*xa;}
int main(){
//freopen("bzoj3437.in","r",stdin);
scanf("%d",&n);
for(rint i=1;i<=n;++i) scanf("%lld",&a[i]);
for(rint i=1;i<=n;++i) scanf("%lld",&b[i]),s[i]=s[i-1]+b[i];
for(rint i=n-1;i;--i) f[n]+=1ll*(n-i)*b[i];
f[n]+=a[n]; ans=f[n]; h[L=R=1]=n;//先把f[n]算出来
for(rint i=n-1;i;--i){
while(L<R&&KK(X(h[L+1])-X(h[L]),Y(h[L+1])-Y(h[L]),
1,s[i])<=0) ++L;

f[i]=f[h[L]]-1ll*(h[L]-i)*s[i]+a[i];
ans=min(ans,f[i]);

while(L<R&&KK(X(h[R])-X(h[R-1]),Y(h[R])-Y(h[R-1]),
X(h[R])-X(i),Y(h[R])-Y(i))>=0) --R;

h[++R]=i;
}printf("%lld",ans);
return 0;
}

4
2424
3142

Sample Output

9

1<=n<=1000000, 0 < a i ,bi < = 10000

Source

posted @ 2019-04-23 21:08  kafuuchino  阅读(148)  评论(0编辑  收藏  举报