zoukankan      html  css  js  c++  java
  • bzoj 1096 仓库建设 —— 斜率优化DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1096

    设 f[i] 为 i 作为最后一个仓库时前 i 个工厂的答案,最后的答案当然是 f[n];

    f[i] = min{ f[j] + ∑(j+1<=k<=i)p[k]*(x[i]-x[k]) + c[i] } , 1<=j<i

    令 s[i] = ∑(1<=j<=i)p[j],t[i] = ∑(1<=j<=i)p[j]*x[j]

    则 f[i] = min{ f[j] + x[i]*(s[i]-s[j]) - (t[i]-t[j]) + c[i] }

    移项,得到 f[j] + t[j] = x[i]*s[j] - x[i]*s[i] + t[i] - c[i] + f[i]

    x[i] 单增,s[j] 单增,可以看出是要维护一个下凸包。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef double db;
    typedef long long ll;
    int const xn=1e6+5;
    int n,x[xn],p[xn],c[xn],q[xn];
    ll s[xn],t[xn],f[xn];
    int rd()
    {
      int ret=0,f=1; char ch=getchar();
      while(ch<'0'||ch>'9'){if(ch=='-')f=0; ch=getchar();}
      while(ch>='0'&&ch<='9')ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();
      return f?ret:-ret;
    }
    db y(int i){return f[i]+t[i];}
    db slp(int a,int b){return (y(b)-y(a))/(s[b]-s[a]);}
    int main()
    {
      n=rd();
      for(int i=1;i<=n;i++)
        {
          x[i]=rd(),p[i]=rd(),c[i]=rd();
          s[i]=s[i-1]+p[i]; t[i]=t[i-1]+(ll)p[i]*x[i];
        }
      int hd=0,tl=0;
      for(int i=1;i<=n;i++)
        {
          while(hd<tl&&slp(q[hd],q[hd+1])<x[i])hd++;
          f[i]=f[q[hd]]+(ll)x[i]*(s[i]-s[q[hd]])-t[i]+t[q[hd]]+c[i];
          while(hd<tl&&slp(q[tl-1],q[tl])>slp(q[tl-1],i))tl--;
          q[++tl]=i;
        }
      printf("%lld
    ",f[n]);
      return 0;
    }
  • 相关阅读:
    计算一个数的逆序数的个数(1)
    Javascript DOM(2)
    python 装饰器
    Javascript DOM
    Javascrip 入门第三节课
    C# sapnco支持.net 4.5了,真是个意外的发现
    uft调用rfc接口
    pyqt常用窗口组件
    python QQTableView中嵌入复选框CheckBox四种方法
    Pygame模块,功能表
  • 原文地址:https://www.cnblogs.com/Zinn/p/9921323.html
Copyright © 2011-2022 走看看