zoukankan      html  css  js  c++  java
  • [bzoj1096][ZJOI2007]仓库建设

    [bzoj1096][ZJOI2007]仓库建设

    标签: DP 斜率优化


    题目链接

    题解

    首先要秒写出dp方程

    [dp[i]=max(dp[j]+sum_{k=j+1}^i p[k](x[i]-x[k])) ]

    [令sp[n]=sum_{i=1}^n p[i],s[n]=sum_{i=1}^n x[i]×p[i] ]

    [方程可简写为dp[i]=max(dp[j]+x[i]×(sp[i]-sp[j])-(s[i]-s[j])) ]

    (设i从j转移过来,取k满足j< k)

    [dp[j]+x[i](sp[i]-sp[j])-(s[i]-s[j])< dp[k]+x[i](sp[i]-sp[j])-(s[i]-s[k]) ]

    [化简,得dp[j]-dp[k]+s[j]-s[k]< x[i](sp[j]-sp[k]) ]

    [frac{dp[j]-dp[k]+s[j]-s[k]}{sp[j]-sp[k]}>x[i] ]

    斜率优化即可。

    Code

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<set>
    #include<map>
    using namespace std;
    #define ll long long
    #define REP(i,a,b) for(int i=(a),_end_=(b);i<=_end_;i++)
    #define DREP(i,a,b) for(int i=(a),_end_=(b);i>=_end_;i--)
    #define EREP(i,a) for(int i=start[(a)];i;i=e[i].next)
    inline int read()
    {
    	int sum=0,p=1;char ch=getchar();
    	while(!(('0'<=ch && ch<='9') || ch=='-'))ch=getchar();
    	if(ch=='-')p=-1,ch=getchar();
    	while('0'<=ch && ch<='9')sum=sum*10+ch-48,ch=getchar();
    	return sum*p;
    }
    
    const int maxn=1e6+20;
    
    int n;
    ll x[maxn],sp[maxn],s[maxn],c[maxn],p[maxn];
    ll dp[maxn];
    
    void init()
    {
    	n=read();
    	REP(i,1,n)
    	{
    		x[i]=read();p[i]=read();c[i]=read();
    		sp[i]=sp[i-1]+p[i];
    		s[i]=s[i-1]+x[i]*p[i];
    	}
    }
    
    double count(int j,int k)
    {
    	return (double)(dp[j]-dp[k]+s[j]-s[k])/(sp[j]-sp[k]);
    }
    
    int q[maxn],head,tail;
    
    void doing()
    {
    	head=1;tail=1;
    	REP(i,1,n)
    	{
    		while(head<tail && count(q[head],q[head+1])<x[i])head++;
    		int xx=q[head];
    		dp[i]=dp[xx]+x[i]*(sp[i]-sp[xx])-s[i]+s[xx]+c[i];
    		while(head<tail && count(q[tail-1],q[tail])>count(q[tail],i))tail--;
    		q[++tail]=i;
    	}
    	printf("%lld
    ",dp[n]);
    }
    
    int main()
    {
    	freopen("factory.in","r",stdin);
    	freopen("factory.out","w",stdout);
    	init();
    	doing();
    	return 0;
    }
    
    
    
  • 相关阅读:
    二维数组和指向指针的指针
    多路复用构建高性能服务器
    disque概要
    漫谈云计算与SOA (1)
    zeromq
    自定义内存分配
    基于行的操作
    反应器类型的操作
    多个流,简短的读和写
    缓存
  • 原文地址:https://www.cnblogs.com/gzy-cjoier/p/7717835.html
Copyright © 2011-2022 走看看