bzoj3437 小P的牧场(斜率优化dp)

3437: 小P的牧场

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

Description

小P在MC里有n个牧场,自西向东呈一字形排列(自西向东用1…n编号),于是他就烦恼了:为了控制这n个牧场,他需要在某些牧场上面建立控制站,每个牧场上只能建立一个控制站,每个控制站控制的牧场是它所在的牧场一直到它西边第一个控制站的所有牧场(它西边第一个控制站所在的牧场不被控制)(如果它西边不存在控制站,那么它控制西边所有的牧场),每个牧场被控制都需要一定的花费(毕竟在控制站到牧场间修建道路是需要资源的嘛~),而且该花费等于它到控制它的控制站之间的牧场数目(不包括自身,但包括控制站所在牧场)乘上该牧场的放养量,在第i个牧场建立控制站的花费是ai,每个牧场i的放养量是bi,理所当然,小P需要总花费最小,但是小P的智商有点不够用了,所以这个最小总花费就由你来算出啦。

 

Input

第一行一个整数 n 表示牧场数目

第二行包括n个整数,第i个整数表示ai

第三行包括n个整数,第i个整数表示bi

 

Output

只有一行,包括一个整数,表示最小花费

 

Sample Input

4
2424
3142

Sample Output

9
样例解释
选取牧场1,3,4建立控制站,最小费用为2+(2+1*1)+4=9。
1<=n<=1000000, 0 < a i ,bi < = 10000

HINT

 

Source


每个控制站控制的牧场是它所在的牧场一直到它西边第一个控制站的所有牧场

这时候逆推显然比正推好用

于是我们设$s[i]$为$b[i]$的前缀和,$f[i]$为只在第$i$~$n$个牧场中设置控制站,且在牧场$i$设置控制站的最小代价

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

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

又化成了喜闻乐见的$y=k*x+b$

$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;
}

Description

小P在MC里有n个牧场,自西向东呈一字形排列(自西向东用1…n编号),于是他就烦恼了:为了控制这n个牧场,他需要在某些牧场上面建立控制站,每个牧场上只能建立一个控制站,每个控制站控制的牧场是它所在的牧场一直到它西边第一个控制站的所有牧场(它西边第一个控制站所在的牧场不被控制)(如果它西边不存在控制站,那么它控制西边所有的牧场),每个牧场被控制都需要一定的花费(毕竟在控制站到牧场间修建道路是需要资源的嘛~),而且该花费等于它到控制它的控制站之间的牧场数目(不包括自身,但包括控制站所在牧场)乘上该牧场的放养量,在第i个牧场建立控制站的花费是ai,每个牧场i的放养量是bi,理所当然,小P需要总花费最小,但是小P的智商有点不够用了,所以这个最小总花费就由你来算出啦。

 

Input

第一行一个整数 n 表示牧场数目

第二行包括n个整数,第i个整数表示ai

第三行包括n个整数,第i个整数表示bi

 

Output

只有一行,包括一个整数,表示最小花费

 

Sample Input

4
2424
3142

Sample Output

9
样例解释
选取牧场1,3,4建立控制站,最小费用为2+(2+1*1)+4=9。
1<=n<=1000000, 0 < a i ,bi < = 10000

HINT

 

Source

原文地址:https://www.cnblogs.com/kafuuchino/p/10758986.html