您的位置:首页 > 其它

BZOJ1096 ZJOI2007 仓库建设

2016-09-19 16:24 197 查看
Description

L公司有N个工厂,由高到底分布在一座山上,工厂1在山顶,工厂N在山脚。由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用。突然有一天,L公司的总裁L先生接到气象部门的电话,被告知三天之后将有一场暴雨,于是L先生决定紧急在某些工厂建立一些仓库以免产品被淋坏。

由于地形的不同,在不同工厂建立仓库的费用可能是不同的。第i个工厂目前已有成品Pi件,在第i个工厂位置建立仓库的费用是Ci。对于没有建立仓库的工厂,其产品应被运往其他的仓库进行储藏,而由于L公司产品的对外销售处设置在山脚的工厂N,故产品只能往山下运(即只能运往编号更大的工厂的仓库),当然运送产品也是需要费用的,假设一件产品运送1个单位距离的费用是1。假设建立的仓库容量都都是足够大的,可以容下所有的产品。

在每一行,你都将得到以下数据:

1.工厂i距离工厂1的距离Xi(其中X1=0)

2.工厂i目前已有成品数量Pi

3.在工厂i建立仓库的费用Ci

请你帮助L公司寻找一个仓库建设的方案,使得总的费用(建造费用+运输费用)最小。

Sample Input & Output

3

0 5 10

5 3 100

9 6 10

32

小P的牧场

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 1000005
int X[M],A[M],B[M];
long long sum1[M],sum2[M],dp[M];
int deq[M],L=0,R=-1,n;
long long calc(int L,int R){return dp[L]+A[R]+(sum1[R]-sum1[L])*X[R]-(sum2[R]-sum2[L]);}
long long up(int L,int R){return dp[R]-dp[L]+sum2[R]-sum2[L];}
long long down(int L,int R){return sum1[R]-sum1[L];}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d %d %d",&X[i],&B[i],&A[i]);
for(int j=1;j<=n;j++){
sum1[j]=sum1[j-1]+B[j];
sum2[j]=sum2[j-1]+1LL*B[j]*X[j];
}
deq[++R]=0;
for(int i=1;i<=n;i++){
while(L<R&&up(deq[L],deq[L+1])<X[i]*down(deq[L],deq[L+1]))++L;
dp[i]=calc(deq[L],i);
while(L<R&&up(deq[R-1],deq[R])*down(deq[R],i)>=down(deq[R-1],deq[R])*up(deq[R],i))--R;
deq[++R]=i;
}
printf("%lld\n",dp
);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  斜率优化dp BZOJ