【题解】
显然,工厂n一定是要建设仓库的,可以设 f[i]:工厂i建设仓库时前i个工厂的最小花费
则:f[i]=min{ sigma( (xi-xk)*pk ) + f[j] +ci },0<=j<i,k从j+1循环到i维护下凸壳,优化之即可
【代码】
#include<stdio.h> #include<stdlib.h> typedef long long LL; LL x[1000005],c[1000005],s[1000005],t[1000005],m[1000005],f[1000005]; int q[1000005]; double K(int j,int k) { return (double)(m[j]-m[k])/(double)(s[j]-s[k]); } int main() { LL p; int n,i,head=0,tail=1; scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%lld%lld%lld",&x[i],&p,&c[i]); s[i]=s[i-1]+p; t[i]=t[i-1]+x[i]*p; } for(i=1;i<=n;i++) { while(tail-head>=2&&K(q[head],q[head+1])<(double)x[i]) head++; f[i]=x[i]*(s[i]-s[q[head]])-(t[i]-t[q[head]])+f[q[head]]+c[i]; m[i]=f[i]+t[i]; while( tail-head >= 2 && K(q[tail-2],q[tail-1]) > (double)(m[q[tail-1]]-m[i])/(double)(s[q[tail-1]]-s[i]) ) tail--; q[tail++]=i; } printf("%lld",f[n]); return 0; }