• [ZJOI2007]仓库建设


    题面在这里

    题意

    L公司有(n)个工厂,由高到底分布在一座山上,工厂1在山顶,工厂N在山脚,工厂(i)到工厂1的距离为(x[i])
    (i)个工厂目前已有成品(p[i])件,在第(i)个工厂位置建立仓库的费用是(c[i])
    对于没有建立仓库的工厂,其产品应被运往其他的仓库进行储藏,而由于L公司产品的对外销售处设置在山脚的工厂(n),故产品只能往山下运(即只能运往编号更大的工厂的仓库),当然运送产品也是需要费用的,假设一件产品运送1个单位距离的费用是1。
    请你帮助L公司寻找一个仓库建设的方案,使得总的费用(建造费用+运输费用)最小。

    数据范围

    (Nle1000000)。 所有的(x[i]),(p[i]),(c[i])均在32位带符号整数以内,保证中间计算结果不超过64位带符号整数。

    sol

    (f[i])表示在第(i)个工厂建立仓库,并将前(i)个工厂里的货物处理完毕的最小费用,那么可以建立一个朴素的方程

    [f[i]=min_{j=0}^{i-1}[f[j]+c[i]+sum_{k=j+1}^{i}p[k](x[i]-x[k])] ]

    [f[i]=min_{j=0}^{i-1}[ f[j]+c[i]+x[i]sum_{k=j+1}^{i}p[k]-sum_{k=j+1}^{i}x[k]p[k] ] ]

    这样使用部分和优化后复杂度是(O(n^2))

    (a[i]=sum_{k=1}^{i}p[k])(b[i]=sum_{k=1}^{i}x[k]p[k]),那么有

    [f[i]=min_{j=0}^{i-1}[f[j]+c[i]+x[i](a[i]-a[j])-(b[i]-b[j])] ]

    [=min_{j=0}^{i-1}(f[j]+b[j]-x[i]a[j])+c[i]+x[i]a[i]-b[i] ]

    (a[j]=x_j)(f[j]+b[j]=y_j)(x[i]=k_i),那么有

    [f[i]-c[i]-x[i]a[i]+b[i]=min_{j=0}^{i-1}(y_j-k_ix_j) ]

    斜率优化完成
    由于(k_i=x[i])单调递增,所以使用单调队列,时间复杂度为(O(n))

    代码

    #include<bits/stdc++.h>
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<iomanip>
    #include<cstring>
    #include<complex>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    #define mp make_pair
    #define pb push_back
    #define RG register
    #define il inline
    using namespace std;
    typedef unsigned long long ull;
    typedef vector<int>VI;
    typedef long long ll;
    typedef double dd;
    const dd eps=1e-10;
    const int mod=1e8;
    const int N=1000010;
    il ll read(){
        RG ll data=0,w=1;RG char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')w=-1,ch=getchar();
        while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
        return data*w;
    }
    
    il void file(){
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
    }
    
    ll n,x[N],p[N],c[N],a[N],b[N],f[N];
    struct node{ll x,y;}Q[N];ll L=1,R;
    il ll query(ll k){
        while(L<R&&k*(Q[L+1].x-Q[L].x)>Q[L+1].y-Q[L].y)L++;
        return Q[L].y-k*Q[L].x;
    }
    il void insert(node q){
        while(L<R&&(Q[R].y-Q[R-1].y)*(q.x-Q[R].x)>(q.y-Q[R].y)*(Q[R].x-Q[R-1].x))R--;
        Q[++R]=q;
    }
    
    int main()
    {
        n=read();
        for(RG int i=1;i<=n;i++){
            x[i]=read();p[i]=read();c[i]=read();
            a[i]=a[i-1]+p[i];b[i]=b[i-1]+x[i]*p[i];
        }
        
        insert((node){0,0});
        for(RG int i=1;i<=n;i++){
            f[i]=query(x[i])+c[i]+x[i]*a[i]-b[i];
            insert((node){a[i],f[i]+b[i]});
        }
        
        printf("%lld
    ",f[n]);
        
        return 0;
    }
    
    
  • 相关阅读:
    UIWebView长按弹出菜单显示英文解决办法
    远程推送不能获取token的原因(证书配置正确)
    汉字转拼音 汉字排序功能
    旋转360度动画
    获取wifi列表
    openssl生成私钥公钥的步骤
    JAVA后台框架优化之日志篇
    react native学习资料
    RAP, 高效前后端联调框架,接口文档管理工具
    【JMeter】JMeter在linux下运行
  • 原文地址:https://www.cnblogs.com/cjfdf/p/8633957.html
Copyright © 2020-2023  润新知