zoukankan      html  css  js  c++  java
  • 【笔记篇】斜率优化dp(四) ZJOI2007仓库建设

    传送门戳这里>>>

    (nleq1e6), 显然还是(O(n))的做法.
    这个题有个条件是只能运往编号更大的工厂的仓库, 这也是写出朴素dp的方程的条件.
    我们令(f[i])表示前(i)个工厂的最小花费, 那么易得

    [f[i]=min{f[j]+t(j,i)} ]

    其中这个(t(j,i))表示将((j,i))这个区间的东西运到(i)的总费用. 很显然, 这个式子要(O(1))求出来才行, 不然复杂度就要炸...
    那么怎么(O(1))求呢?
    考虑类似于前缀和的性质.
    这里写图片描述
    我们令(s_i)为将((1,i])这个区间中所有工厂的产品运到(i)的总花费, (c_i)表示前(i)个工厂的产品总量, (d_i)表示第(i)个工厂的坐标, 我们发现, 如果对(i,j)做一波前缀和相减, 那么前(j)个点的货物都被多运了(d_i-d_j)的距离... 所以就可以推出

    [t(j,i)=s_i-s_j-c_j*(d_i-d_j) ]

    这样就可以扔进状态转移方程进行斜率优化了... 化完之后的式子是:
    (f[j]-s[j]+c[j]*d[j])=(d[i])(c[j])+(f[i]-s[i]-w[i])
    然后求的是最小值, 斜率还递增(这好像是最常见的一种了吧?), 那就跟之前一样咯= =
    然而还是把演草纸上(d[i],c[j])的数组名抄反了WA了一次 但为什么可以过样例啊QAQ
    然后就是没有压行的代码: (简单的斜率优化似乎总可以写成标准的20行?

    #include <cstdio>
    const int N=1e6+6;
    typedef long long LL;
    LL f[N],s[N],c[N];
    int q[N],w[N],d[N],n,h,t;
    inline int gn(int a=0,char c=0){
    	for(;c<'0'||c>'9';c=getchar());
    	for(;c>47&&c<58;c=getchar())a=a*10+c-48;return a;
    }
    double slope(int x,int y){
    	return 1.0*(f[x]-s[x]+c[x]*d[x]-f[y]+s[y]-c[y]*d[y])/(c[x]-c[y]);
    }
    int main(){
    	n=gn();	for(int i=1;i<=n;++i){
    		d[i]=gn();c[i]=c[i-1]+gn();w[i]=gn();
    		s[i]=s[i-1]+c[i-1]*(d[i]-d[i-1]);
    	}
    	for(int i=1,j;i<=n;++i){
    		while(h<t&&slope(q[h],q[h+1])<=d[i]) ++h; j=q[h];
    		f[i]=f[j]+s[i]-s[j]-c[j]*(d[i]-d[j])+w[i];
    		while(h<t&&slope(q[t],q[t-1])>=slope(q[t],i)) --t;
    		q[++t]=i;
    	}
    	printf("%lld
    ",f[n]);
    }
    
  • 相关阅读:
    我的WCF之旅(1):创建一个简单的WCF程序
    网页设计中颜色的搭配
    CSS HACK:全面兼容IE6/IE7/IE8/FF的CSS HACK
    UVa 1326 Jurassic Remains
    UVa 10340 All in All
    UVa 673 Parentheses Balance
    UVa 442 Matrix Chain Multiplication
    UVa 10970 Big Chocolate
    UVa 679 Dropping Balls
    UVa 133 The Dole Queue
  • 原文地址:https://www.cnblogs.com/enzymii/p/8413698.html
Copyright © 2011-2022 走看看