BZOJ2331 [SCOI2011]地板

Time Limit: 5 Sec  Memory Limit: 128 MB
Submit: 1104  Solved: 468

Description

 

lxhgww的小名叫L”,这是因为他总是很喜欢L型的东西。小L家的客厅是一个的矩形,现在他想用L型的地板来铺满整个客厅,客厅里有些位置有柱子,不能铺地板。现在小L想知道,用L型的地板铺满整个客厅有多少种不同的方案?

需要注意的是,如下图所示,L型地板的两端长度可以任意变化,但不能长度为0。铺设完成后,客厅里面所有没有柱子的地方都必须铺上地板,但同一个地方不能被铺多次。

Input

输入的第一行包含两个整数,RC,表示客厅的大小。

接着是R行,每行C个字符。’_’表示对应的位置是空的,必须铺地板;’*’表示对应的位置有柱子,不能铺地板。

Output

输出一行,包含一个整数,表示铺满整个客厅的方案数。由于这个数可能很大,只需输出它除以20110520的余数。

Sample Input

2 2

*_

__

Sample Output

1

HINT

 

R*C<=100

 

Source

 

插头DP

状态转移还是看代码吧233

 

  1 /*by SilverN*/
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<cmath>
  7 #include<vector>
  8 #define LL long long
  9 using namespace std;
 10 const int p=100007;
 11 const int mod=20110520;
 12 const int mxn=2000100;
 13 int now,pre;
 14 struct edge{
 15     int v,nxt,id;
 16 }e[2][mxn];
 17 int hd[2][mxn],mct[2]={0};
 18 LL f[2][mxn];
 19 void add(int v,LL w){//hash
 20     int z=v%p;
 21     for(int i=hd[now][z];i;i=e[now][i].nxt){
 22         if(e[now][i].v==v){
 23             f[now][i]=(f[now][i]+w)%mod;
 24             return;
 25         }
 26     }
 27     e[now][++mct[now]]=(edge){v,hd[now][z],z};hd[now][z]=mct[now];
 28     f[now][mct[now]]=w;
 29     return;
 30 }
 31 int n,m;
 32 char mp[125][125];
 33 char tmp[125][125];
 34 int b[25];
 35 int main(){
 36     int i,j;
 37     for(i=1;i<=20;i++)b[i]=i<<1;
 38     //
 39     scanf("%d%d",&n,&m);
 40     for(i=1;i<=n;i++)
 41         scanf("%s",mp[i]+1);
 42     if(n<m){
 43         for(i=1;i<=n;i++)
 44             for(j=1;j<=m;j++)
 45                 tmp[j][i]=mp[i][j];
 46         swap(n,m);
 47         memcpy(mp,tmp,sizeof tmp);
 48     }
 49 /*    
 50     //test
 51     for(i=1;i<=n;i++){
 52         for(j=1;j<=m;j++){
 53             printf("%c ",mp[i][j]);
 54         }
 55         printf("\n");
 56     }
 57 */    
 58     memset(f,0,sizeof f);
 59     now=0;pre=1;
 60     add(0,1);
 61     for(i=1;i<=n;i++){//
 62         for(j=1;j<=mct[now];j++) e[now][j].v<<=2;//整体左移 
 63         for(j=1;j<=m;j++){//
 64             swap(now,pre);
 65             for(int k=1;k<=mct[now];k++)hd[now][e[now][k].id]=0;
 66             mct[now]=0;
 67             //clear
 68             for(int k=1;k<=mct[pre];k++){
 69                 int v=e[pre][k].v;
 70                 int x=v>>b[j-1]&3;//提取左一位
 71                 int y=v>>b[j]&3;//提取当前位
 72                 LL w=f[pre][k];
 73                 if(mp[i][j]=='*'){if(!(x|y))add(v,w);}//柱子
 74                 //以下为地板情况 
 75                     else if(x==1 && y==1){ // 11->00
 76                         add(v^(1<<b[j])^(1<<b[j-1]),w);
 77                     }
 78                     else if(x+y==0){ //
 79                         if(mp[i+1][j]=='_')add(v^(1<<b[j-1]),w);
 80                         if(mp[i][j+1]=='_')add(v^(1<<b[j]),w);
 81                         if(mp[i+1][j]=='_' && mp[i][j+1]=='_')add(v^(2<<b[j-1])^(2<<b[j]),w);
 82                     }
 83                     else if(x==1 && !y){ //10 -> 20  01
 84                         if(mp[i+1][j]=='_')add(v+(1<<b[j-1]),w);
 85                         if(mp[i][j+1]=='_')add(v^(1<<b[j-1])^(1<<b[j]),w);
 86                     }
 87                     else if(!x && y==1){ //01 -> 10  02
 88                         if(mp[i+1][j]=='_')add(v^(1<<b[j-1])^(1<<b[j]),w);
 89                         if(mp[i][j+1]=='_')add(v+(1<<b[j]),w);
 90                     }
 91                     else if(x==2 && !y){ //20 -> 00  02
 92                         add(v^(2<<b[j-1]),w);
 93                         if(mp[i][j+1]=='_')add(v^(2<<b[j-1])^(2<<b[j]),w);
 94                     }
 95                     else if(!x && y==2){ //02 -> 00  20
 96                         add(v^(2<<b[j]),w);
 97                         if(mp[i+1][j]=='_')add(v^(2<<b[j-1])^(2<<b[j]),w);
 98                     }
 99             }
100         }
101     }
102     if(mct[now])printf("%lld\n",f[now][1]);
103         else printf("0\n");
104     return 0;
105 }

 

posted @ 2017-02-26 19:31  SilverNebula  阅读(243)  评论(0编辑  收藏  举报
AmazingCounters.com