• BZOJ1096: [ZJOI2007]仓库建设


    Description

      L公司有N个工厂,由高到底分布在一座山上。如图所示,工厂1在山顶,工厂N在山脚。由于这座山处于高原内
    陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用。突然有一天,L公司的总裁L先生接到气象
    部门的电话,被告知三天之后将有一场暴雨,于是L先生决定紧急在某些工厂建立一些仓库以免产品被淋坏。由于
    地形的不同,在不同工厂建立仓库的费用可能是不同的。第i个工厂目前已有成品Pi件,在第i个工厂位置建立仓库
    的费用是Ci。对于没有建立仓库的工厂,其产品应被运往其他的仓库进行储藏,而由于L公司产品的对外销售处设
    置在山脚的工厂N,故产品只能往山下运(即只能运往编号更大的工厂的仓库),当然运送产品也是需要费用的,
    假设一件产品运送1个单位距离的费用是1。假设建立的仓库容量都都是足够大的,可以容下所有的产品。你将得到
    以下数据:1:工厂i距离工厂1的距离Xi(其中X1=0);2:工厂i目前已有成品数量Pi;:3:在工厂i建立仓库的费用
    Ci;请你帮助L公司寻找一个仓库建设的方案,使得总的费用(建造费用+运输费用)最小。

    Input

      第一行包含一个整数N,表示工厂的个数。接下来N行每行包含两个整数Xi, Pi, Ci, 意义如题中所述。

    Output

      仅包含一个整数,为可以找到最优方案的费用。

    Sample Input

    3
    0 5 10
    5 3 100
    9 6 10

    Sample Output

    32

    HINT

    在工厂1和工厂3建立仓库,建立费用为10+10=20,运输费用为(9-5)*3 = 12,总费用32。如果仅在工厂3建立仓库,建立费用为10,运输费用为(9-0)*5+(9-5)*3=57,总费用67,不如前者优。

    【数据规模】

    对于100%的数据, N ≤1000000。 所有的Xi, Pi, Ci均在32位带符号整数以内,保证中间计算结果不超过64位带符号整数。 

    Source


    斜率优化
    设f[i]表示第i个工厂建立仓库的前i个工厂得到解决的最小花费
    则f[i]=min{f[k]+cost[k+1,i] | 0<=k<i } + C[i]
    容易得出
    cost[L,R]=P[L]+(x[R]-x[L])+P[L+1]*(x[R]-x[L+1])+……+P[R]*(x[R]-x[R])
    =x[R]*(P[L~R])-(x[L]*P[L]+x[L+1]*P[L+1]+……+x[R]*P[R])
    记sumP[i]=P[1~i]
    sumPX[i]=x[1]*P[1]+x[2]*P[2]+……+x[i]*P[i]
    则f[i]=min{f[k]+sumP[i]*x[i]-sumP[k]*x[i]-sumPX[i]+sumPX[k] | 0<=k<i } + C[i]
    =min{f[k]-sumP[k]*x[i]+sumPX[k] | 0<=k<i } + sumP[i]*x[i]-sumPX[i]+C[i]
    发现{}里面的是f[k]-sumP[k]*x[i]+sumPX[k],拿出来研究
    1)证明决策单调性
    设在状态i下 j<k k比j更优 则有:
    f[k]-sumP[k]*x[i]+sumPX[k]<f[j]-sumP[j]*x[i]+sumPX[j]             (1)
    则在状态t下(t>i)若有
    f[k]-sumP[k]*x[t]+sumPX[k]<f[j]-sumP[j]*x[t]+sumPX[j]
    (发现x[i]是关于i的增函数,t>i则x[t]>x[i],设x[t]=x[i]+v(v>0))
    即f[k]-sumP[k]*(x[i]+v)+sumPX[k]<f[j]-sumP[j]*(x[i]+v)+sumPX[j]
    即f[k]-sumP[k]*x[i]+sumPX[k]<f[j]-sumP[j]*[i]+sumPX[j] 且 -sumP[k]*v<-sumP[j]*v
    由(1)及sumP[i]是增函数可知,命题成立
    2)写出斜率方程
    若f[k]-sumP[k]*x[i]+sumPX[k]<=[j]-sumP[j]*x[i]+sumPX[j]
    则(f[k]-f[j]-sumPX[k]+sumPX[j])/(sumP[k]-sumP[j])<=x[i]

    故当(f[k]-f[j]-sumPX[k]+sumPX[j])/(sumP[k]-sumP[j])<=x[i]时,若有j<k,那么k比j更优
    由于是小于号,所以斜率越大,随着x[i]的增大,被选中的几乎更大,
    所以l到r:     斜率 小——>大
    优劣程度是:优劣 优——>劣

     1 /**************************************************************
     2     Problem: 1096
     3     User: white_hat_hacker
     4     Language: C++
     5     Result: Accepted
     6     Time:1980 ms
     7     Memory:51604 kb
     8 ****************************************************************/
     9  
    10 #include<cstdio>
    11 #include<cstdlib>
    12 #include<algorithm>
    13 #include<cstring>
    14 #include<cmath>
    15 #include<map>
    16 #include<set>
    17 #include<queue>
    18 #include<vector>
    19 #define INF 0x7f7f7f7f
    20 #define pii pair<int,int>
    21 #define ll long long
    22 #define MAXN 1000005
    23 using namespace std;
    24 int read(){
    25     int x=0,f=1;char ch=getchar();
    26     while(ch<'0'||ch>'9'){if('-'==ch)f=-1;ch=getchar();}
    27     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    28     return x*f;
    29 }
    30 int n;
    31 ll x[MAXN],P[MAXN],C[MAXN];
    32 ll sumP[MAXN],sumPX[MAXN];
    33 int q[MAXN];
    34 ll f[MAXN];
    35 double slope(int k,int j){
    36     return (f[k]-f[j]-sumPX[j]+sumPX[k])/(1.0*(sumP[k]-sumP[j]));
    37 }
    38  
    39 int main()
    40 {
    41 //  freopen("data.in","r",stdin);
    42     n=read();
    43     for(int i=1;i<=n;i++){
    44         x[i]=read();
    45         P[i]=read();
    46         C[i]=read();
    47         sumP[i]=sumP[i-1]+P[i];
    48         sumPX[i]=sumPX[i-1]+P[i]*x[i];
    49     }
    50     int l=1,r=0;
    51     q[++r]=0;
    52     for(int i=1;i<=n;i++){
    53         while(l<r&&slope(q[l],q[l+1])<=(double)x[i]) l++;
    54         int t=q[l];
    55         f[i]=f[t]-sumP[t]*x[i]+sumPX[t]+sumP[i]*x[i]-sumPX[i]+C[i];
    56         while(l<r&&slope(i,q[r])<slope(q[r-1],q[r])) r--;
    57         q[++r]=i;
    58     }
    59     printf("%lld
    ",f[n]);
    60     return 0;
    61 }
     
     
  • 相关阅读:
    Java入门
    Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8
    pypy3.8安装
    asyncio执行阻塞代码
    linux安装go
    python消费rabbitmq
    绑定进程到指定cpu运行
    负载均衡算法
    django版本规划
    FastAPI WebSocket 简单演示
  • 原文地址:https://www.cnblogs.com/w-h-h/p/7739398.html
Copyright © 2020-2023  润新知