【斜率优化】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 }