[bzoj1096]仓库建设

f[i]:=1~i的最小花费

f[i]:=min{f[j]+Sigmaik=j+1(x[i]-x[k])*p[k]}+c[i]

然后斜率优化。

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cstdlib>
 6 using namespace std;
 7 
 8 typedef long long ll;
 9 const int N=1000010;
10 int x[N],p[N],c[N],n;
11 ll f[N],G[N],W[N],l,r;
12 typedef pair<ll,ll> poi;
13 poi q[N];
14 
15 double tan2(poi a,poi b){
16     if(a.first==b.first)return a.second<b.second?1e12:-1e12;
17     return (double)(a.second-b.second)/(a.first-b.first);
18 }
19 void ins(poi x){
20     while(r-l>1&&tan2(q[r],x)<tan2(q[r],q[r-1]))
21         r--;
22     q[++r]=x;
23 }
24 poi ans(double slope){
25     while(r-l>1&&tan2(q[l+1],q[l+2])<slope)
26         l++;
27     return q[l+1];
28 }
29 
30 int main(){
31     scanf("%d",&n);
32     for(int i=1;i<=n;i++){
33         scanf("%d%d%d",&x[i],&p[i],&c[i]);
34         G[i]=G[i-1]+p[i];
35         W[i]=W[i-1]+(ll)x[i]*p[i];
36     }
37     for(int i=1;i<=n;i++){
38         ins(poi(G[i-1],f[i-1]+W[i-1]));
39         poi p=ans(x[i]);
40         f[i]=p.second+x[i]*G[i]-x[i]*p.first-W[i]+c[i];
41     }
42     printf("%lld\n",f[n]);
43 }
View Code

 

posted @ 2017-01-29 10:53  KingSann  阅读(108)  评论(0)    收藏  举报