【bzoj3734】小P的牧场 斜率优化dp

来源:互联网 发布:蓝桥物流软件多少钱 编辑:程序博客网 时间:2024/05/22 05:15

AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=3437


【题解】

f[i]表示前i个牧场被控制的最小代价,sumb表示b数组的前缀和,sumkb表示 b[i]*i 的前缀和
 
则状态转移方程:f[i]=min{f[j]+a[i]+i*(sumb[i]-sumb[j])-(sumkb[i]-sumkb[j])}  (1<=j<i)
 
设j<k,且从k转移到i比j更优。
 
得斜率表达式:[(f[j]-sumkb[j])-(f[k]-sumkb[k])]/(sumb[j]-sumb[k])>i

/*************  bzoj 3437  by chty  2016.11.14*************/#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<ctime>#include<cmath>#include<algorithm>using namespace std;typedef long long ll;#define FILE "read"#define MAXN 1000100#define up(i,j,n) for(ll i=j;i<=n;i++)namespace INIT{char buf[1<<15],*fs,*ft;inline char getc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;}inline ll read(){ll x=0,f=1;  char ch=getc();while(!isdigit(ch))  {if(ch=='-')  f=-1;  ch=getc();}while(isdigit(ch))  {x=x*10+ch-'0';  ch=getc();}return x*f;}}using namespace INIT;ll n,head,tail,a[MAXN],b[MAXN],sumb[MAXN],sumkb[MAXN],q[MAXN],f[MAXN];void init(){n=read();up(i,1,n) a[i]=read();up(i,1,n) b[i]=read(),sumb[i]=sumb[i-1]+b[i],sumkb[i]=sumkb[i-1]+b[i]*i;}inline double slop(ll j,ll k) {return (double)((f[j]+sumkb[j])-(f[k]+sumkb[k]))/(double)(sumb[j]-sumb[k]);}void solve(){up(i,1,n){while(head<tail&&slop(q[head],q[head+1])<i)  head++;ll t=q[head];f[i]=f[t]+a[i]+i*(sumb[i]-sumb[t])-(sumkb[i]-sumkb[t]);while(head<tail&&slop(q[tail-1],q[tail])>slop(q[tail],i))  tail--;q[++tail]=i;}printf("%lld\n",f[n]);}int main(){freopen(FILE".in","r",stdin);freopen(FILE".out","w",stdout);init();solve();return 0;}



1 0
原创粉丝点击