【BZOJ1096】仓库建设

来源:互联网 发布:电信内蒙古大数据 编辑:程序博客网 时间:2024/06/01 21:44

题解:
f[i]表示处理完前i个仓库的最小花费
DP方程化一化,就是个斜率单增,横坐标单增的斜率优化啦
和【BZOJ1010】是一样的

//by sdfzchy#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef long long LL;const int inf=(1<<30),N=2000010;int n,m;inline int in(){    char ch=getchar();    int f=1,tmp=0;    while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}    while(ch>='0'&&ch<='9') {tmp=(tmp<<1)+(tmp<<3)+(ch-'0');ch=getchar();}    return tmp*f;}LL sump[N],sum[N],dis[N],f[N],c[N],p[N];int q[N],l=1,r;inline LL gi(int x) {return f[x]+sum[x];}inline LL ga(int x) {return sump[x];}double calc(double x,double y){    return ((double)gi(y)-gi(x))/((double)ga(y)-ga(x));}int main(){    n=in();    for(int i=1;i<=n;i++) dis[i]=in(),p[i]=in(),c[i]=in();    for(int i=1;i<=n;i++) sump[i]=sump[i-1]+p[i],sum[i]=sum[i-1]+dis[i]*p[i];    f[0]=0; q[++r]=0;    for(int i=1;i<=n;i++)    {        while(l<r&&calc(q[l],q[l+1])<dis[i]) l++;        int j=q[l];        f[i]=f[j]+dis[i]*(sump[i]-sump[j])-sum[i]+sum[j]+c[i];        while(l<r&&calc(q[r-1],q[r])>calc(q[r],i)) --r;        q[++r]=i;    }    printf("%lld\n",f[n]);    return 0;}
原创粉丝点击