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/ 转载请注明出处,侵权必究,保留最终解释权!
  • 相关阅读:
    Poj 1742 Coins(多重背包)
    Poj 2350 Above Average(精度控制)
    求二进制数中1的个数
    Poj 1659 Distance on Chessboard(国际象棋的走子规则)
    Poj 2411 Mondriaan's Dream(压缩矩阵DP)
    Poj 2136 Vertical Histogram(打印垂直直方图)
    Poj 1401 Factorial(计算N!尾数0的个数——质因数分解)
    poj 2390 Bank Interest(计算本利和)
    Poj 2533 Longest Ordered Subsequence(LIS)
    Poj 1887 Testing the CATCHER(LIS)
  • 原文地址:https://www.cnblogs.com/Dragon-Light/p/6491852.html
Copyright © 2011-2022 走看看