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 }

 

 

posted @ 2013-01-18 22:59  proverbs  阅读(941)  评论(0编辑  收藏