背景
小P是个特么喜欢玩MC的孩纸。。。
描述
小P在MC里有n个牧场,自西向东呈一字形排列(自西向东用1…n编号),于是他就烦恼了:为了控制这n个牧场,他需要在某些牧场上面建立控制站,每个牧场上只能建立一个控制站,每个控制站控制的牧场是它所在的牧场一直到它西边第一个控制站的所有牧场(它西边第一个控制站所在的牧场不被控制)(如果它西边不存在控制站,那么它控制西边所有的牧场),每个牧场被控制都需要一定的花费(毕竟在控制站到牧场间修建道路是需要资源的嘛~),而且该花费等于它到控制它的控制站之间的牧场数目(不包括自身,但包括控制站所在牧场)乘上该牧场的放养量,在第i个牧场建立控制站的花费是ai,每个牧场i的放养量是bi,理所当然,小P需要总花费最小,但是小P的智商有点不够用了,所以这个最小总花费就由你来算出啦。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<deque>
#include<set>
#include<map>
#include<ctime>
#define LL long long
#define inf 10000000000000000ll
#define pa pair<int,int>
#define pi 3.1415926535897932384626433832795028841971
#define N 1000010
using namespace std;
inline LL read()
{
LL x=0,f=1;char ch=getchar();
while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
return x*f;
}
LL s[N],t[N],f[N];
int a[N],b[N];
int q[N],head,tail=1;
LL cala(int x,int y)
{
return f[x]-f[y]-(t[x]-t[y])+(s[x]*(x+1)-s[y]*(y+1));
}
LL calb(int x,int y)
{
return s[x]-s[y];
}
int n;
int main() //f[i]=min(f[j]+a[i]+t[i-1]-t[j]-s[j]*(i-j-1));
{
freopen("pasture.in","r",stdin);
freopen("pasture.out","w",stdout);
n=read();
for (int i=1;i<=n;i++)f[i]=inf;
for (int i=1;i<=n;i++)a[i]=read();
for (int i=1;i<=n;i++)b[i]=read();
for (int i=1;i<=n;i++)
{
s[i]=s[i-1]+b[i];
t[i]=t[i-1]+s[i];
}
for (int i=1;i<=n;i++)
{
while (tail-head>1 && cala(q[head+1],q[head])<=i*calb(q[head+1],q[head]))head++;
int from=q[head];
f[i]=f[from]+a[i]+t[i-1]-t[from]-s[from]*(i-from-1);
q[tail++]=i;
for (int k=tail-2;k>head;k--)
{
int x=q[k+1],y=q[k],z=q[k-1];
if (cala(y,z)*calb(x,y)>=cala(x,y)*calb(y,z))q[k]=q[--tail];
else break;
}
}
printf("%lld\n",f[n]);
}