zoukankan      html  css  js  c++  java
  • [ZJOI2007]仓库建设

    洛咕

    题意:(N(N<=1000000))个工厂,1到N编号,每个工厂给定距离工厂1的距离(x_i),该工厂物品数量(p_i),该工厂建造仓库的费用(c_i).在几个工厂上建立仓库,没建仓库的工厂要将物品运输到有仓库的工厂,运输费用为物品数量乘两个工厂之间的距离,求最小总花费(建造仓库的费用+运输费用)

    分析:设(f[i])表示在i工厂建立仓库的最小总花费.则有(f[i]=f[j]+c[i]+sum_{k=j+1}^{i-1}p[k]*(x[i]-x[k]))

    (sumv[i])表示将1到i-1号工厂的所有物品运到i的总运输费用,(sump[i])表示前i个工厂的物品总数,则有

    (f[i]=f[j]+c[i]+sumv[i]-sumv[j]-sump[j]*(x[i]-x[j]))

    (k<j)且j比k更优,即

    (f[j]+c[i]+sumv[i]-sumv[j]-sump[j]*(x[i]-x[j])<f[k]+c[i]+sumv[i]-sumv[k]-sump[k]*(x[i]-x[k]))

    整理一下上式得到,

    (frac{f[j]-sumv[j]+x[j]*sump[j]-f[k]+sumv[k]-x[k]*sump[k]}{sum[j]-sum[k]}<x[i])

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    inline int read(){
        int s=0,w=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
        return s*w;
    }
    const int N=1000005;
    int x[N],p[N],c[N],q[N];
    LL sump[N],sumv[N],f[N];
    inline double check(int a,int b){return 1.0*(f[a]-sumv[a]+x[a]*sump[a]-f[b]+sumv[b]-x[b]*sump[b])/(sump[a]-sump[b]);}
    int main(){
        int n=read();
        for(int i=1;i<=n;i++){
    		x[i]=read();p[i]=read();c[i]=read();
    		sump[i]=sump[i-1]+p[i];
    		sumv[i]=sumv[i-1]+sump[i-1]*(x[i]-x[i-1]);
    		f[i]=1e18;
        }
        int l=1,r=1;
        for(int i=1;i<=n;i++){
    		while(l<r&&check(q[l+1],q[l])<=x[i])l++;
    		f[i]=f[q[l]]+c[i]+sumv[i]-sumv[q[l]]-(x[i]-x[q[l]])*sump[q[l]];
    		while(l<r&&check(q[r],q[r-1])>=check(i,q[r]))r--;
    		q[++r]=i;
        }
        printf("%lld
    ",f[n]);
        return 0;
    }
    
    
  • 相关阅读:
    url传递参数带 + ,解决办法
    操作系统——内存地址重定位
    算法——二分查找变形题
    Java——代码性能优化
    maven——添加插件和添加依赖有什么区别?
    JavaWeb——Servlet如何调用线程池中的线程?
    「ZJOI2016」小星星
    [十二省联考2019]字符串问题
    [十二省联考2019]春节十二响
    [十二省联考2019]异或粽子
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11007457.html
Copyright © 2011-2022 走看看