[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 }