• bzoj 1096: [ZJOI2007]仓库建设


    同样是一个斜率优化,设f[i]表示在i处建仓库,f[i] = f[j] + cal(j,i) + c[i];

    一开始cal想了我好久,一直只想到o(n)cal。。。

    后面看着花花想cal的实现,一下子就想出来了!!!

    斜率优化的一般方法应该是 f[i] + 只与i有关的看作c,只与j有关的看作by,与ij有关的j看作x,i看作a,再用向量积去做

    等下再用决策单调性优化写下这道题。。

    妈蛋一开始队列写错了卡了15分钟!!!最近老是犯些SB错误。。还是静不下来啊

     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
    ",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
    ",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
    ",f[n]);
    70     return 0;
    71 }
    View Code

    感觉斜率优化式子写出来以后比决策单调性还好写些(>__<)

  • 相关阅读:
    实现单台测试机6万websocket长连接
    关于ArcGIS10.0中的栅格计算中的函数
    .NET破解之迅捷PDF转换器(续)
    ArcEngine 0x8004023C
    VS2010中重命名项目
    地理数据库本身不能加密
    ArcEngine尝试读取或写入受保护的内存
    利用路由器连接别人家的网络
    ArcGIS的许可文件问题
    MapGIS转Shp文件的单位问题
  • 原文地址:https://www.cnblogs.com/wulala979/p/3515346.html
Copyright © 2020-2023  润新知