【斜率优化】BZOJ1096-[ZJOI2007]仓库建设

【题目大意】

有n个工厂编号分别为1-n,第i个仓库库存量为p[i],距离第1个仓库的距离为x[i](x[1]=0)。在每一个工厂建立一个仓库费用为c[i],没有建立仓库的工厂只能往编号大于它的仓库运送,费用为每单位库存量单位距离费用为1。问最少的总费用?(建仓库费用+运送费用)

【思路】

注意一下凸包怎么维护...

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cstdlib>
 6 using namespace std;
 7 const int MAXN=1000000+50;
 8 typedef long long ll;
 9 int n,d[MAXN],c[MAXN];
10 ll psum[MAXN],pdsum[MAXN],f[MAXN],y[MAXN];
11 int que[MAXN];
12 
13 double slop(int i,int j)
14 {
15     ll x1=psum[i];
16     ll x2=psum[j];
17     ll y1=f[i]+pdsum[i];
18     ll y2=f[j]+pdsum[j];
19     return(1.0*(y2-y1)/(x2-x1));
20 }
21 
22 void init()
23 {
24     scanf("%d",&n);
25     memset(psum,0,sizeof(psum));
26     memset(pdsum,0,sizeof(pdsum));
27     memset(f,0,sizeof(f));
28     for (int i=1;i<=n;i++)
29     {
30         int p;
31         scanf("%d%d%d",&d[i],&p,&c[i]);
32         psum[i]=psum[i-1]+(ll)p;
33         pdsum[i]=pdsum[i-1]+(ll)p*d[i];
34     }
35 }
36 
37 ll dp()
38 {
39     int head=0,tail=1;
40     for (int i=1;i<=n;i++)
41     {
42         while (head+1<tail && slop(que[head],que[head+1])<=1.0*d[i]) head++;
43         int j=que[head];
44         f[i]=d[i]*psum[i]-pdsum[i]+c[i]+f[j]-d[i]*psum[j]+pdsum[j];
45         while (head+1<tail && slop(que[tail-1],i)<=slop(que[tail-2],que[tail-1])) tail--;
46         que[tail++]=i;
47     }
48     return(f[n]);
49 }
50 
51 int main()
52 {
53     init();
54     printf("%lld\n",dp());
55     return 0;
56 } 

 

posted @ 2016-07-06 13:40  iiyiyi  阅读(57)  评论(0编辑  收藏