zoukankan      html  css  js  c++  java
  • 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("
    ");
     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
    ",f[now][1]);
    103         else printf("0
    ");
    104     return 0;
    105 }
  • 相关阅读:
    DataGrid和GridView鼠标移动上面背景变色
    Javascript页面跳转常用代码(测试通过)
    设为首页,加入收藏夹
    Javascript实现金额千分位自动分位
    对用户输入内容进行字数提示功能
    Javascript网页刷新方法集锦(测试通过)
    asp.net 上传图片并作处理 水印 缩略图(测试OK)
    ASP.NET常用函数(参考用)
    Javascript弹出对话框 确定取消转到不同页面
    silverligth +wcf 下载文件
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6445525.html
Copyright © 2011-2022 走看看