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

    https://loj.ac/problem/10189

    题目描述

      有(N)个工厂建在山上,每个工厂之间有一定的距离,每个工厂有一定的成品和在这个工厂建仓库的代价。成品只能往山脚运,当前(N)有一个仓库,求再建若干个仓库后所有成品运至仓库的最小代价。

    思路

      由于产品只能从山上往山下运,所以运的必定会是连续的一段,我们记(f[i])为前(i)个工厂的最小代价,记(sum)(p)的前缀和,(s)(p*x[i])的前缀和,那么方程为

    [f[i]=min{f[j]+sum_{k=j+1}^i p[k]*(x[i]-x[k])}\ f[i]=min{f[j]+x[i]*(sum[i]-sum[j])-s[i]+s[j]} ]

      化简为一次函数的形式后为

    [f[j]+[j]=x[i]*sum[j]-x[i]*sum[i]+s[i]+f[i] ]

      斜率优化维护一下下凸壳求最小截距即可。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll N=1e6+10;
    
    ll read()
    {
    	ll res=0,w=1;
    	char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){res=(res<<3)+(res<<1)+(ch^48);ch=getchar();}
    	return res*w;
    }
    
    ll sum[N],s[N],q[N],f[N],x[N],c[N];
    int main()
    {
    	ll n=read();
    	for(ll i=1;i<=n;i++)
    	{
    		ll p;
    		x[i]=read(),p=read(),c[i]=read();
    		sum[i]=sum[i-1]+p;
    		s[i]=s[i-1]+(p*x[i]);
    	}
    	ll head=0,tail=0;
    	for(ll i=1;i<=n;i++)
    	{
    		while(head<tail&&(f[q[head+1]]+s[q[head+1]]-f[q[head]]-s[q[head]])
    				<=x[i]*(sum[q[head+1]]-sum[q[head]]))head++;
    		f[i]=f[q[head]]+x[i]*(sum[i-1]-sum[q[head]])-s[i-1]+s[q[head]]+c[i];
    		while(head<tail&&(f[q[tail]]+s[q[tail]]-f[q[tail-1]]-s[q[tail-1]])*(sum[i]-sum[q[tail]])
    				>=(f[i]+s[i]-f[q[tail]]-s[q[tail]])*(sum[q[tail]]-sum[q[tail-1]]))tail--;
    		q[++tail]=i;
    	}
    	printf("%lld",f[n]);
    }
    
  • 相关阅读:
    Flask入门到精通(二)
    MySQL安装配置,命令,异常纪要
    JQuery 选择器
    redhat Enterprise Linux Server release 7.2(Maipo) 安装redis-stat
    pssh 不能执行指定用户命令
    VMware 命令行下安装以及导入Ubuntu系统
    Linux CPU相关信息查看
    Ubuntu 16.04 Mxnet CPU 版本安装
    Ubuntu 16.04 TensorFlow CPU 版本安装
    <转>揭秘DNS后台文件:DNS系列之五
  • 原文地址:https://www.cnblogs.com/fangbozhen/p/11853440.html
Copyright © 2011-2022 走看看