当前位置: 代码迷 >> 综合 >> 【BZOJ1096】仓库建设
  详细解决方案

【BZOJ1096】仓库建设

热度:55   发布时间:2024-01-13 09:50:37.0

题解:
f[i]表示处理完前i个仓库的最小花费
DP方程化一化,就是个斜率单增,横坐标单增的斜率优化啦
和【BZOJ1010】是一样的

//by sdfzchy
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int inf=(1<<30),N=2000010;
int n,m;
inline int in()
{char ch=getchar();int f=1,tmp=0;while(ch<'0'||ch>'9') {
   if(ch=='-') f=-1;ch=getchar();}while(ch>='0'&&ch<='9') {tmp=(tmp<<1)+(tmp<<3)+(ch-'0');ch=getchar();}return tmp*f;
}LL sump[N],sum[N],dis[N],f[N],c[N],p[N];
int q[N],l=1,r;inline LL gi(int x) {
   return f[x]+sum[x];}
inline LL ga(int x) {
   return sump[x];}double calc(double x,double y)
{return ((double)gi(y)-gi(x))/((double)ga(y)-ga(x));
}
int main()
{n=in();for(int i=1;i<=n;i++) dis[i]=in(),p[i]=in(),c[i]=in();for(int i=1;i<=n;i++) sump[i]=sump[i-1]+p[i],sum[i]=sum[i-1]+dis[i]*p[i];f[0]=0; q[++r]=0;for(int i=1;i<=n;i++){while(l<r&&calc(q[l],q[l+1])<dis[i]) l++;int j=q[l];f[i]=f[j]+dis[i]*(sump[i]-sump[j])-sum[i]+sum[j]+c[i];while(l<r&&calc(q[r-1],q[r])>calc(q[r],i)) --r;q[++r]=i;}printf("%lld\n",f[n]);return 0;
}