zoukankan      html  css  js  c++  java
  • BZOJ1096 仓库建设

    BZOJ1096 仓库建设

    题目传送门

    题解

    也是一道比较经典的斜率优化(Dp),很容易推出DP转移方程:
    (dp[i]=min(dp[j]+cost(i,j))+c[i])

    重点就是怎么快速的算出cost(i,j)。我们把cost的计算公式写出来:
    (cost(i,j)=sum_{k=j+1}^ip[k]*(x[i]−x[k])=x[i]*sum_{k=j+1}^ip[k]-sum_{k=j+1}^ip[k]*x[k])

    我们记sum[i]为p[i]的前缀和,b[i]为p[i]∗x[i]的前缀和,那么DP转移就是:
    (dp[i]=min(dp[j]+x[i]*(sum[i)−sum[j])−(b[i])−b[j])+c[i])

    于是我们就可以愉悦的用斜率优化来做这道题了,如果k>j并且k比j更优,那么:
    (dp[j]+x[i]*(sum[i]sum[j])−(b[i])−b[j]≥dp[k]+x[i]*(sum[i)−sum[k])−(b[i])−b[k])

    整理一下可得:
    (dp[k]−dp[j]+b[k]−b[j]sum[k]−sum[j]≤s[i])

    最后就是套用斜率优化的步骤了。

    code

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    bool Finish_read;
    template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;}
    template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x%10+'0');}
    template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('
    ');}
    template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);}
    /*================Header Template==============*/
    #define PAUSE printf("Press Enter key to continue..."); fgetc(stdin);
    const int maxn=1e6+500;
    int n;
    ll dis[maxn],c[maxn],p[maxn],f[maxn],sum[maxn],b[maxn];
    int l,r;
    int que[maxn];
    /*==================Define Area================*/
    double Cal(int x,int y) {
    	return (double)(f[y]-f[x]+b[y]-b[x])/(double)(sum[y]-sum[x]);
    }
    
    int main() {
    	read(n);
    	for(int i=1;i<=n;i++) {
    		read(dis[i]);read(p[i]);read(c[i]);
    	}
    	for(int i=1;i<=n;i++) {
    		sum[i]=sum[i-1]+p[i];
    		b[i]=b[i-1]+p[i]*dis[i];
    	}
    	for(int i=1;i<=n;i++) {
    		while(l<r&&Cal(que[l],que[l+1])<dis[i]) l++;
    		int t=que[l];
    		f[i]=f[t]-b[i]+b[t]+(sum[i]-sum[t])*dis[i]+c[i];
    		while(l<r&&Cal(que[r-1],que[r])>Cal(que[r],i)) r--;
    		que[++r]=i;
    	}
    	printf("%lld
    ",f[n]);
    	return 0;
    }
    
    「我不敢下苦功琢磨自己,怕终于知道自己并非珠玉;然而心中既存着一丝希冀,便又不肯甘心与瓦砾为伍。」
  • 相关阅读:
    设置linux查看历史命令显示执行时间
    CentOS7.6操作系统安装实例以及Linux版本、哲学思想介绍
    JavaScript 数据结构1
    原生js 正则表达
    js Event事件
    引用类型: 归并方法
    引用类型: 迭代方法
    引用类型 位置方法 indexOf()和 lastIndexOf()
    引用类型 操作方法
    引用类型 重排序方法
  • 原文地址:https://www.cnblogs.com/Apocrypha/p/9434923.html
Copyright © 2011-2022 走看看