zoukankan      html  css  js  c++  java
  • 【BZOJ】2331: [SCOI2011]地板

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2331


    一眼插头DP...

    考虑一个L形的东西,要构成它可以划分为两个阶段,即当前线段是拐了弯的还是没有拐弯的。
    所以$4$进制表示,$0$表示没有插头,$1$表示插头指向拐点,$2$表示插头离开拐点。

    转移:

    令${(x,y)}$表示当前点左插头和上插头的形态。

    ${(0,0)}$------>${(0,1)}$,${(1,0)}$,${(2,2)}$

    ${(0,1)}$------>${(1,0)}$,${(0,2)}$

    ${(0,2)}$------>${(0,0)}$,${(2,0)}$

    ${(1,0)}$------>${(0,1)}$,${(2,0)}$

    ${(2,0)}$------>${(0,0)}$,${(0,2)}$

    当然如果有障碍就不能走。


      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<vector>
      5 #include<cstdlib>
      6 #include<cmath>
      7 #include<cstring>
      8 using namespace std;
      9 #define maxn 10010
     10 #define llg long long 
     11 #define SIZE 10007
     12 #define md 20110520
     13 #define maxnZT (1<<21)
     14 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
     15 llg n,m,code[maxn],zt[2][maxnZT],v[2][maxnZT],g[110][110],size[2],now,la;
     16 
     17 struct node
     18 {
     19     llg pos,x,val;
     20 };
     21 
     22 vector<node>a[2][SIZE];
     23 
     24 void outcode(llg x){for (llg i=0;i<=m;i++) code[i]=x&3,x>>=2;}
     25 
     26 void encode(llg p,llg val)
     27 {
     28     llg x=0;
     29     for (llg i=0;i<=m;i++) x+=code[i]*(1<<(i*2));
     30     llg wz=x%SIZE,E=a[p][wz].size();
     31     for (llg i=0;i<E;i++)
     32         if (a[p][wz][i].x==x)
     33         {
     34             a[p][wz][i].val+=val;  a[p][wz][i].val%=md;
     35             v[p][a[p][wz][i].pos]+=val; v[p][a[p][wz][i].pos]%=md;
     36             return ;
     37         }
     38     size[p]++;
     39     node NEW;
     40     NEW.pos=size[p],NEW.x=x,NEW.val=val;
     41     a[p][wz].push_back(NEW);
     42     zt[p][size[p]]=x; v[p][size[p]]=val;
     43 }
     44 
     45 void init()
     46 {
     47     cin>>n>>m;
     48     char ch;
     49     for (llg i=1;i<=n;i++)
     50         for (llg j=1;j<=m;j++)
     51         {
     52             ch=getchar();
     53             while (ch!='*' && ch!='_') ch=getchar();
     54             if (n<m) g[j][i]=(ch=='_');
     55             else g[i][j]=(ch=='_');
     56         }
     57     if (n<m) swap(n,m);
     58 }
     59 
     60 void init_a(llg p){for (llg i=0;i<SIZE;i++) a[p][i].clear(); size[p]=0;}
     61 
     62 void DP()
     63 {
     64     llg le,up,V;
     65     encode(0,1);
     66     for (llg i=1;i<=n;i++)
     67     {
     68         for (llg k=1;k<=size[now];k++) zt[now][k]*=4;//轮廓线左移一格
     69         for (llg j=1;j<=m;j++)
     70         {
     71             now^=1; la=now^1; size[now]=0;
     72             init_a(now);
     73             for (llg k=1;k<=size[la];k++)
     74             {
     75                 outcode(zt[la][k]);
     76                 le=code[j-1],up=code[j],V=v[la][k];//提取左插头和上插头
     77             
     78                 if (g[i][j]==0)
     79                 {
     80                     if (le==0 && up==0) encode(now,V);
     81                     continue;
     82                 }
     83 
     84                 if (!le && !up)
     85                 {
     86                     if (j<m && g[i][j+1]==1)
     87                     {
     88                         code[j-1]=0,code[j]=1;
     89                         encode(now,V);
     90                         if (g[i+1][j]==1)
     91                         {
     92                             code[j-1]=code[j]=2;
     93                             encode(now,V);
     94                         }
     95                     }
     96                     if (g[i+1][j]==1)
     97                     {
     98                         code[j-1]=1,code[j]=0;
     99                         encode(now,V);
    100                     }
    101                     continue;
    102                 }
    103 
    104                 if (le && up)
    105                 {
    106                     if (le==1 && up==1)
    107                     {
    108                         code[j-1]=code[j]=0;
    109                         encode(now,V);
    110                     }
    111                     continue;
    112                 }
    113                 
    114                 if (le==1 && up==0)
    115                 {
    116                     if (g[i+1][j]==1)
    117                     {
    118                         code[j-1]=2;
    119                         encode(now,V);
    120                     }
    121                     if (g[i][j+1]==1 && j<m)
    122                     {
    123                         code[j]=1; code[j-1]=0;
    124                         encode(now,V);
    125                     }
    126                     continue;
    127                 }
    128 
    129                 if (le==2 && up==0)
    130                 {
    131                     if (j<m && g[i][j+1]==1)
    132                     {
    133                         code[j]=2; code[j-1]=0;
    134                         encode(now,V);
    135                     }
    136                     code[j]=code[j-1]=0;
    137                     encode(now,V);
    138                     continue;
    139                 }
    140 
    141                 if (le==0 && up==1)
    142                 {
    143                     if (g[i+1][j]==1)
    144                         {
    145                             code[j-1]=1,code[j]=0;
    146                             encode(now,V);
    147                         }
    148                     if (j<m && g[i][j+1]==1)
    149                     {
    150                         code[j-1]=0; code[j]=2;
    151                         encode(now,V);
    152                     }
    153                     continue;
    154                 }
    155                 
    156                 if (le==0 && up==2)
    157                 {
    158                     if (g[i+1][j]==1)
    159                     {
    160                         code[j]=0,code[j-1]=2;
    161                         encode(now,V);
    162                     }
    163                     code[j-1]=code[j]=0;
    164                     encode(now,V);
    165                     continue;
    166                 }
    167             }
    168         }
    169     }
    170 }
    171 
    172 int main()
    173 {
    174     yyj("BZOJ2331");
    175     init();
    176     DP();
    177     llg ans=0;
    178     bool pd;
    179     for (llg i=1;i<=size[now];i++)
    180     {
    181         outcode(zt[now][i]);
    182         pd=true;
    183         for (llg j=0;j<=m;j++) if (code[j]) pd=false;
    184         if (pd) ans+=v[now][i];
    185     }
    186     cout<<ans%md;
    187     return 0;
    188 }
    本文作者:xrdog 作者博客:http://www.cnblogs.com/Dragon-Light/ 转载请注明出处,侵权必究,保留最终解释权!
  • 相关阅读:
    Linux TCP/IP 连接查看和问题解决
    Linux Tomcat 7.0 管理员登录时"401 Unauthorized" 问题解决方法
    Tomcat 性能监控工具jvisualvm, JConsole
    Tomcat 实战-调优方案
    Linux Tomcat8 访问管理页面 403 Access Denied
    docker redis
    Spring Boot 定时任务
    Nginx rewrite使用
    五 python 发送邮件
    关于注解继承性的一个例子
  • 原文地址:https://www.cnblogs.com/Dragon-Light/p/6491852.html
Copyright © 2011-2022 走看看