码迷,mamicode.com
首页 > 其他好文 > 详细

【bzoj1096】仓库建设——斜率优化dp

时间:2017-09-01 22:21:57      阅读:229      评论:0      收藏:0      [点我收藏+]

标签:代码   bsp   getc   while   class   过程   har   double   etc   

题目链接

我们用sum[i]表示前i个工厂的产品数之和,b[i]表示x[i]*p[i]的前缀和,因此第j+1~i个工厂的产品运到第i个工厂的代价就是

  (sum[i]-sum[j])*x[i]-(b[i]-b[j])+ci[i]

最后f[i]的状态转移方程即为:

  f[i]=f[j]+(sum[i]-sum[j])*xi[i]-(b[i]-b[j])+ci[i]

斜率式的推导过程就不写了,最后可以化成:

  (f[j]+b[j]-f[k]-b[k])/(sum[j]-sum[k])<xi[i]-ci[i](k<j<i)

//然而刚开始最后的那个加号写成乘号导致WA了两次,要注意队列的q[0]=0(不是1!!!),还是要细心吧。

代码:

 

技术分享
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 typedef long long LL;
 5 const int maxn=1000010;
 6 using namespace std;
 7 LL xi[maxn],pi[maxn],ci[maxn],sum[maxn],b[maxn],f[maxn],q[maxn];
 8 inline LL read()
 9 {
10     LL anss=0,f=1;char c=getchar();
11     while(c<0||c>9){if(c==-)f=-1;c=getchar();}
12     while(c>=0&&c<=9){anss=anss*10+c-48;c=getchar();}
13     return anss*f;
14 }
15 inline double cal(LL a,LL bb)
16 {
17     return 1.0*(f[a]+b[a]-f[bb]-b[bb])/(sum[a]-sum[bb]);
18 }
19 int main()
20 {
21     int n;
22     n=read();
23     sum[0]=0;b[0]=0;
24     for(int i=1;i<=n;i++){
25         xi[i]=read();pi[i]=read();ci[i]=read();
26         sum[i]=sum[i-1]+pi[i];
27         b[i]=b[i-1]+xi[i]*pi[i];
28     }
29     int h=0,t=1;q[0]=0;f[0]=0;
30     for(int i=1;i<=n;i++){
31         while(h<t-1&&cal(q[h],q[h+1])<xi[i])h++;
32         f[i]=f[q[h]]+(sum[i]-sum[q[h]])*xi[i]-(b[i]-b[q[h]])+ci[i];
33         while(h<t-1&&cal(q[t-2],q[t-1])>cal(q[t-1],i))t--;
34         q[t++]=i;
35     }
36     printf("%lld",f[n]);
37     return 0;
38 }
bzoj1096

 

【bzoj1096】仓库建设——斜率优化dp

标签:代码   bsp   getc   while   class   过程   har   double   etc   

原文地址:http://www.cnblogs.com/JKAI/p/7465176.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!