BZOJ 1096 [ZJOI2007]仓库建设
转移特别显然是n^2的,tle~
然后由于转移没有区间限制,所以应该不是单调队列,然后想斜率优化吧。
推了两张纸,证明了决策的单调性(我以前都是默认的单调。。。第一次证明。),嘿嘿。
其实就是维护的一个下凸的函数。
View Code
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cstring> 6 7 #define N 1100000 8 9 using namespace std; 10 11 int n; 12 long long x[N],p[N],sump[N],sum[N],c[N],dp[N],q[N]; 13 14 inline void read() 15 { 16 scanf("%d",&n); 17 for(int i=1;i<=n;i++) 18 { 19 scanf("%lld%lld%lld",&x[i],&p[i],&c[i]); 20 sump[i]=sump[i-1]+p[i]; 21 sum[i]=sum[i-1]+p[i]*x[i]; 22 } 23 } 24 25 inline long long V(int u,int s) 26 { 27 return dp[u]+sum[u]-dp[s]-sum[s]; 28 } 29 30 inline long long G(int u) 31 { 32 return x[u]*sump[u]-sum[u]+c[u]; 33 } 34 35 inline void go() 36 { 37 int h=1,t=1; 38 q[1]=0; 39 for(int i=1;i<=n;i++) 40 { 41 while(h<t&&V(q[h+1],q[h])<x[i]*(sump[q[h+1]]-sump[q[h]])) h++; 42 dp[i]=dp[q[h]]+sum[q[h]]-x[i]*sump[q[h]]+G(i); 43 while(h<t&&V(q[t],i)*(sump[q[t-1]]-sump[q[t]])<=V(q[t-1],q[t])*(sump[q[t]]-sump[i])) t--; 44 q[++t]=i; 45 } 46 printf("%lld\n",dp[n]); 47 } 48 49 int main() 50 { 51 read(); 52 go(); 53 return 0; 54 }
没有人能阻止我前进的步伐,除了我自己!