BZOJ 1096 仓库建设

Posted on 2016-12-26 16:11  ziliuziliu  阅读(70)  评论(0编辑  收藏

和上题类似吧。。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 1000050
using namespace std;
long long n,x[maxn],p[maxn],c[maxn],sum1[maxn],sum2[maxn],f[maxn],q[maxn],l,r,g[maxn];
long long read()
{
    char ch;long long data=0;
    while (ch<'0' || ch>'9') ch=getchar();
    while (ch>='0' && ch<='9')
    {
        data=data*10+ch-'0';
        ch=getchar();
    }
    return data;
}
double k(long long a,long long b)
{
    return (double)(g[a]-g[b])/(x[a]-x[b]);
}
void dp()
{
    l=r=1;q[l]=1;g[1]=c[1];f[1]=c[1];
    for (long long i=2;i<=n;i++)
    {
        g[i]=f[i-1]+c[i]-sum1[i]+sum2[i]*x[i];
        while ((r-l) && (k(q[r-1],q[r])>k(q[r],i))) r--;
        q[++r]=i;
        while ((r-l) && (k(q[l],q[l+1])<=sum2[i])) l++;
        f[i]=f[q[l]-1]+c[q[l]]+sum1[i]-sum1[q[l]]-(sum2[i]-sum2[q[l]])*x[q[l]];
    }
}
int main()
{
    n=read();
    for (register long long i=1;i<=n;i++) x[i]=read(),p[i]=read(),c[i]=read();
    for (register long long i=1;i<=n;i++) x[i]=x[n]-x[i];
    for (register long long i=1;i<=n/2;i++) swap(p[i],p[n-i+1]),swap(c[i],c[n-i+1]),swap(x[i],x[n-i+1]);
    for (register long long i=1;i<=n;i++)
    {
        sum1[i]=sum1[i-1]+p[i]*x[i];
        sum2[i]=sum2[i-1]+p[i];
    }
    dp();
    printf("%lld\n",f[n]);
    return 0;
}