zoukankan      html  css  js  c++  java
  • BZOJ3336: Uva10572 Black and White(插头Dp)

    解题思路:

    分类讨论即可。

    代码(懒得删Debug了):

      1 #include<map>
      2 #include<cstdio>
      3 #include<vector>
      4 #include<cstring>
      5 #include<algorithm>
      6 #define black '#'
      7 #define white 'o'
      8 #define BLACK_AND_WHITE int main(){/*freopen("a.in","r",stdin);*/scanf("%d",&T);while(T--)Black_and_White();return 0;}
      9 typedef long long lnt;
     10 typedef unsigned int uit;
     11 typedef unsigned long long unt;
     12 int T;
     13 int n,m;
     14 int p,q;
     15 unt ans=0;
     16 int mp[20][20];
     17 char cmd[100];
     18 uit code[100];
     19 uit tod[100];
     20 int clor[31];
     21 bool col[100];
     22 std::map<unt,unt>dp[2],ooo;
     23 void minpress(uit *cd)
     24 {
     25     int cnt=0;
     26     memset(clor,0,sizeof(clor));
     27     for(int i=0;i<=m;i++)
     28     {
     29         if(!clor[cd[i]])
     30             clor[cd[i]]=++cnt;
     31         cd[i]=clor[cd[i]];
     32     }
     33     return ;
     34 }
     35 unt compress(uit *cd,int hc)
     36 {
     37     unt ret=hc;
     38     minpress(cd);
     39     for(int i=0;i<=m;i++)
     40         ret=ret*10ull+cd[i];
     41     return ret;
     42 }
     43 void decompress(uit *cd,bool *cl,unt sit)
     44 {
     45     for(int i=m;i>=0;i--)
     46     {
     47         cd[i]=sit%10ull;
     48         sit/=10ull;
     49     }
     50     cl[0]=sit;
     51     for(int i=1;i<=m;i++)
     52         if(cd[i]!=cd[i-1])
     53             cl[i]=1-cl[i-1];
     54         else
     55             cl[i]=cl[i-1];
     56     return ;
     57 }
     58 bool banned(int l,int r,int pos,uit *cd)
     59 {
     60     for(int i=0;i<l;i++)
     61         if(cd[i]==cd[pos-1])
     62             return false;
     63     for(int i=r-1;i<=m;i++)
     64         if(cd[i]==cd[pos-1])
     65             return false;
     66     return true;
     67 }
     68 void update(int cmd,unt tmp,unt v)
     69 {
     70     if(dp[cmd].find(tmp)==dp[cmd].end())
     71         dp[cmd][tmp]=v;
     72     else
     73         dp[cmd][tmp]+=v;
     74     return ;
     75 }
     76 void Insert(int ii,int jj,unt s,unt v,bool b)
     77 {    
     78     decompress(code,col,s);
     79     int lu,uu,ll,hc=col[0];
     80 /*    printf("%d ",hc);
     81     for(int k=0;k<=m;k++)
     82         printf("%d ",code[k]);
     83     printf("%d",v);
     84 /*    puts("");/*
     85     for(int i=0;i<=m;i++)
     86     printf("%d ",col[i]);*/
     87     uu=col[jj]^b;
     88     lu=col[jj-1]^b;
     89     ll=col[jj-2]^b;
     90 /*    printf(uu?"b":"w");
     91     printf(lu?"b":"w");
     92     printf(ll?"b":"w");*/
     93 //    puts("");
     94     uit maxs=0;
     95     for(int i=0;i<=m;i++)
     96         maxs=std::max(maxs,code[i]);
     97     for(int i=0;i<=m;i++)
     98         tod[i]=code[i];
     99     if(ll)
    100     {
    101         if(lu)
    102         {
    103             if(uu)
    104                 tod[jj-1]=maxs+1;
    105             else
    106                 tod[jj-1]=tod[jj];
    107         }else{
    108             if(uu)
    109             {
    110                 if(ii==n&&jj==m)
    111                     return ;
    112                 if(banned(jj-2,jj+2,jj+1,tod))
    113                     return ;
    114                 //printf("+1
    ");
    115                 tod[jj-1]=maxs+1;
    116             }else
    117                 tod[jj-1]=tod[jj];
    118         }
    119     }else{
    120         if(lu)
    121         {
    122             if(uu)
    123             {
    124                 if(banned(jj-2,jj+2,jj+1,tod))
    125                 {
    126                     if(ii!=n||(jj!=m&&jj!=m-1))return ;
    127                     for(int i=0;i<jj-2;i++)
    128                         if(col[i]==col[jj])
    129                             return ;
    130                     for(int i=jj+1;i<=m;i++)
    131                         if(col[i]==col[jj])
    132                             return ;
    133                 }
    134                 tod[jj-1]=tod[jj-2];
    135             }else{
    136                 tod[jj]=tod[jj-1]=tod[jj-2];
    137                 for(int i=0;i<=m;i++)
    138                 {
    139                     if(code[i]==code[jj]||code[i]==code[jj-2])
    140                         tod[i]=tod[jj-2];
    141                 }
    142             }
    143         }else{
    144             if(uu)
    145             {
    146                 if(banned(jj-2,jj+2,jj+1,tod))
    147                 {
    148                     if(ii!=n||(jj!=m&&jj!=m-1))return ;
    149                     for(int i=0;i<jj-2;i++)
    150                         if(col[i]==col[jj])
    151                             return ;
    152                     for(int i=jj+1;i<=m;i++)
    153                         if(col[i]==col[jj])
    154                             return ;
    155                 }
    156                 tod[jj-1]=tod[jj-2];
    157             }else return ;
    158         }
    159     }
    160     unt tmp=compress(tod,hc);
    161     if(ii==n&&jj==m)
    162     {
    163         int cnt=0;
    164         decompress(code,col,tmp);
    165         memset(clor,0,sizeof(clor));
    166         for(int i=0;i<=m;i++)
    167             if(!clor[code[i]])
    168                 clor[code[i]]=++cnt;
    169         if(cnt<=2)
    170             ans+=v;
    171         return ;
    172     }
    173     update(p,tmp,v);
    174     return ;
    175 }
    176 void Insert(int i,unt s,unt v,bool b)
    177 {
    178     decompress(code,col,s);
    179     int uu,hc=col[0];
    180 /*    printf("%d ",hc);
    181     for(int k=0;k<=m;k++)
    182         printf("%d ",code[k]);
    183     printf("%d ",v);
    184     puts("");*/
    185     for(int i=0;i<=m;i++)
    186         tod[i]=code[i];
    187     uu=col[1]^b;
    188     if(uu)
    189     {
    190         if(banned(0,3,2,tod))
    191             return ;
    192         code[0]=0;
    193         hc=b;
    194     }else
    195         code[0]=code[1];
    196     unt tmp=compress(code,hc);
    197     if(i==n&&m==1)
    198     {
    199         int cnt=0;
    200         decompress(code,col,tmp);
    201         memset(clor,0,sizeof(clor));
    202         for(int ii=0;ii<=m;ii++)
    203             if(!clor[code[ii]])
    204                 clor[code[ii]]=++cnt;
    205         if(cnt<=2)
    206             ans+=v;
    207     }
    208     update(p,tmp,v);
    209     return ;
    210 }
    211 unt move(unt x)
    212 {
    213     decompress(code,col,x);
    214     int hc=col[0];
    215     for(int i=m;i;i--)
    216         code[i]=code[i-1];
    217     return compress(code,hc);
    218 }
    219 void Move(void)
    220 {
    221     ooo.clear();
    222     for(std::map<unt,unt>::iterator i=dp[p].begin();i!=dp[p].end();i++)
    223         ooo[i->first]=i->second;
    224     dp[p].clear();
    225     for(std::map<unt,unt>::iterator i=ooo.begin();i!=ooo.end();i++)
    226     {
    227         update(p,move(i->first),i->second);
    228 //        printf("%I64u %I64u
    ",move(i->first),i->second);
    229     }
    230     return ;
    231 }
    232 void Black_and_White(void)
    233 {
    234     dp[0].clear();
    235     dp[1].clear();
    236     ans=0;
    237     p=1,q=0;
    238     memset(mp,0,sizeof(mp));
    239     memset(code,0,sizeof(code));
    240     memset(clor,0,sizeof(clor));
    241     scanf("%d%d",&n,&m);
    242     for(int i=1;i<=n;i++)
    243     {
    244         scanf("%s",cmd+1);
    245         for(int j=1;j<=m;j++)
    246         {
    247             if(cmd[j]==white)
    248                 mp[i][j]=-1;
    249             else if(cmd[j]==black)
    250                 mp[i][j]=1;
    251             else
    252                 mp[i][j]=0;            
    253         }
    254     }
    255     if(n==1&&m==1)
    256     {
    257         if(mp[1][1])
    258             puts("2");
    259         else
    260             puts("1");
    261         return ;
    262     }
    263     for(int i=0;i<(1<<m);i++)
    264     {
    265         int cnt=1;
    266         code[0]=code[1]=1;
    267         bool ban=false;
    268         for(int j=1;j<=m;j++)
    269         {
    270             if(mp[1][j]==1&&((i&(1<<(j-1)))==0))ban=true;
    271             if(mp[1][j]==-1&&(i&(1<<(j-1))))    ban=true;
    272             if(ban)break;
    273         }
    274         if(ban)
    275             continue;
    276         for(int j=2;j<=m;j++)
    277         {
    278             if((bool)(i&(1<<(j-1)))^(bool)(i&(1<<(j-2))))
    279                 cnt++;
    280             code[j]=cnt;
    281         }
    282         int co=i&1;
    283 //        printf("%d ",co);
    284 //        puts("");
    285         unt s=compress(code,co);
    286 //        printf("%d
    ",s);
    287         update(p,s,1);
    288     }
    289     for(int i=2;i<=n;i++)
    290     {
    291 //        puts("
    ~~~~~~~~~~~~~~~~~~~~~~");
    292         std::swap(p,q);
    293         dp[p].clear();
    294         for(std::map<unt,unt>::iterator k=dp[q].begin();k!=dp[q].end();k++)
    295         {
    296             unt s=k->first;
    297             unt v=k->second;
    298             if(mp[i][1]!=1)
    299                 Insert(i,s,v,0);
    300             if(mp[i][1]!=-1)
    301                 Insert(i,s,v,1);
    302         }
    303 //        puts("_________________________");
    304         for(int j=2;j<=m;j++)
    305         {
    306 //            puts("
    ~~~~~~~~~~~~~~~~~~~~~~");    
    307             std::swap(p,q);
    308             dp[p].clear();
    309             for(std::map<unt,unt>::iterator k=dp[q].begin();k!=dp[q].end();k++)
    310             {
    311                 unt s=k->first;
    312                 unt v=k->second;
    313                 if(mp[i][j]!=1)
    314                     Insert(i,j,s,v,0);
    315                 if(mp[i][j]!=-1)
    316                     Insert(i,j,s,v,1);
    317             }
    318 //            puts("_________________________");
    319         }
    320     //    puts("%d");
    321         Move();
    322     }
    323     printf("%llu
    ",ans);
    324     return ;
    325 }BLACK_AND_WHITE
  • 相关阅读:
    2014-2-24 日记
    The C++ Programming Language
    穷举法练习题
    JAVA的语法基础3
    JAVA的语法基础 练习题
    JAVA的语法基础2
    JAVA的语法基础1
    代码结构和标识符
    Eclipse使用
    Java开发环境
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10205761.html
Copyright © 2011-2022 走看看