# BZOJ1096 仓库建设

### 题解

$dp[i]=min(dp[j]+cost(i,j))+c[i]$

$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]$

$dp[i]=min(dp[j]+x[i]*(sum[i)−sum[j])−(b[i])−b[j])+c[i]$

$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]$

### ｃｏｄｅ

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
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('\n');}
template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);}
#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() {
for(int i=1;i<=n;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\n",f[n]);
return 0;
}

posted @ 2018-08-07 08:26  Apocrypha  阅读(76)  评论(0编辑  收藏