【题目大意】

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

【思路】

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

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

 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 } 

 

相关文章:

  • 2021-05-25
  • 2022-02-10
  • 2022-12-23
  • 2021-09-01
  • 2021-09-04
  • 2021-11-28
  • 2021-05-27
猜你喜欢
  • 2021-06-17
  • 2021-07-21
  • 2022-01-24
  • 2021-06-05
  • 2021-06-14
  • 2022-12-23
  • 2022-03-02
相关资源
相似解决方案