# bzoj 1096: [ZJOI2007]仓库建设

 1 /*
2 ID:WULALA
3 PROB:bzoj1096_slope
4 LANG:C++
5 */
6 #include <cstdio>
7 #include <cstring>
8 #include <algorithm>
9 #include <cmath>
10 #include <iostream>
11 #include <ctime>
12 #include <set>
13 #define N 1000008
14 #define M
15 #define mod
16 #define mid(l,r) ((l+r) >> 1)
17 #define INF 0x7ffffff
18 using namespace std;
19
20 long long l,r,n,p[N],que[N],f[N],d[N],c[N],s[N],sum[N];
21
22 void init()
23 {
24     scanf("%lld",&n);
25     for (int i = 1;i <= n;i++)
26     {
27         scanf("%lld%lld%lld",&d[i],&p[i],&c[i]);
28         s[i] = s[i-1] + sum[i-1] * (d[i] - d[i-1]);
29         sum[i] = sum[i-1] + p[i];
30     }
31     l = r = 1;
32 }
33
34 long long cal(long long x,long long y)
35 {
36     long long r = (f[x] + s[y] - s[x] - sum[x] * (d[y] - d[x]) + c[y]);
37     return r;
38 }
39
40 long long cross(long long o,long long a,long long b)
41 {
42     long long xo = sum[o],yo = f[o] - s[o] + sum[o] * d[o];
43     long long xa = sum[a],ya = f[a] - s[a] + sum[a] * d[a];
44     long long xb = sum[b],yb = f[b] - s[b] + sum[b] * d[b];
45     xa -= xo; ya -= yo;
46     xb -= xo; yb -= yo;
47     return (xa * yb - xb * ya);
48 }
49
50 void debug(long long a)
51 {
52     printf("%lld %lld\n",que[l],f[a]);
53 }
54
55 int main()
56 {
57     init();
58     for (int i = 1;i <= n;i++)
59     {
60         while (l < r && cal(que[l],i) > cal(que[l+1],i))
61             l++;
62         f[i] = cal(que[l],i);
63 //        debug(i);
64         while (l < r && cross(que[r-1],que[r],i) < 0) r--;
65         que[++r] = i;
66     }
67     printf("%lld\n",f[n]);
68     return 0;
69 }
View Code

决策单调性

 1 /*
2 ID:WULALA
3 PROB:bzoj1096_mono
4 LANG:C++
5 */
6 #include <cstdio>
7 #include <cstring>
8 #include <algorithm>
9 #include <cmath>
10 #include <iostream>
11 #include <ctime>
12 #include <set>
13 #define N 1000008
14 #define M
15 #define mod
16 #define mid(l,r) ((l+r) >> 1)
17 #define INF 0x7ffffff
18 using namespace std;
19
20 long long l,r,n,p[N],que[N],f[N],d[N],c[N],s[N],sum[N],st[N];
21
22 void init()
23 {
24     scanf("%lld",&n);
25     for (int i = 1;i <= n;i++)
26     {
27         scanf("%lld%lld%lld",&d[i],&p[i],&c[i]);
28         s[i] = s[i-1] + sum[i-1] * (d[i] - d[i-1]);
29         sum[i] = sum[i-1] + p[i];
30     }
31     for (int i = 1;i <= n+1;i++) st[i] = n + 1;
32     l = r = 1; st[0] = 1;
33 }
34
35 long long cal(long long x,long long y)
36 {
37     long long r = (f[x] + s[y] - s[x] - sum[x] * (d[y] - d[x]) + c[y]);
38     return r;
39 }
40
41 long long find(long long a)
42 {
43     long long top = r + 1,bot = l;//top应= r + 1;!!
44     while (bot != top)
45     {
46         if (st[que[mid(bot,top)]] <= a) bot = mid(bot,top) + 1;
47         else top = mid(bot,top);
48     }
49     return (bot - 1);
50 }
51
52 int main()
53 {
54     init();
55     for (int i = 1;i <= n;i++)
56     {
57         f[i] = cal(que[find(i)],i);
58         while (r && cal(que[r],st[que[r]]) > cal(i,st[que[r]])) r--;
59         int bot = st[que[r]],top = n + 1;
60         while (bot != top)
61         {
62             if (cal(que[r],mid(top,bot)) > cal(i,mid(top,bot))) top = mid(top,bot);
63             else bot = mid(top,bot) + 1;
64         }
65         if (bot == n + 1) continue;
66         que[++r] = i;
67         st[i] = bot;
68     }
69     printf("%lld\n",f[n]);
70     return 0;
71 }
View Code

posted @ 2014-01-11 21:14  乌拉拉979  阅读(87)  评论(0编辑  收藏