zoukankan      html  css  js  c++  java
  • bzoj 2331 [SCOI2011]地板 插头dp

    2331: [SCOI2011]地板

    Time Limit: 5 Sec  Memory Limit: 128 MB
    Submit: 1436  Solved: 606
    [Submit][Status][Discuss]

    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

    Day1

    题解,因为每个位置都需要铺满,那么而且只有L型插头,

    所以有三种类型

    0表示没有插头,1表示插头还没有拐过弯,2表示插头已经拐过弯了。

    然后分析合并的状态,用hash的方法去记录状态,不然如果运用位运算的话,

    空间存不下,用hash的方式,这样在CDQ的论文中有讲到,这样的方法比较优秀的,

    1.00-->22 或 10 或 01

     

    2.11-->00

     

    3.10-->20 或 01

       20-->00 或 02

     

    4.01-->10 或 02

       02-->00 或 20

      1 #pragma GCC optimize(2)
      2 #pragma G++ optimize(2)
      3 #include<iostream>
      4 #include<algorithm>
      5 #include<cmath>
      6 #include<cstdio>
      7 #include<cstring>
      8 
      9 #define N 107
     10 #define M 200007
     11 #define mod 20110520
     12 using namespace std;
     13 inline int read()
     14 {
     15     int x=0,f=1;char ch=getchar();
     16     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
     17     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
     18     return x*f;
     19 }
     20 
     21 int n,m,now,pre,cnt;
     22 int a[N][N],f[2][M],tot[2],hash[2][M];
     23 int hed[M],nxt[M],v[M],bit[N];
     24 char s[N];
     25 
     26 void ins(int sta,int shu)
     27 {
     28     int x=sta%50000;
     29     for (int i=hed[x];i;i=nxt[i])
     30         if(hash[now][v[i]]==sta)
     31         {
     32             (f[now][v[i]]+=shu)%=mod;
     33             return;
     34         }
     35     tot[now]++;
     36     hash[now][tot[now]]=sta;
     37     f[now][tot[now]]=shu;
     38     cnt++,v[cnt]=tot[now],nxt[cnt]=hed[x],hed[x]=cnt;
     39 }
     40 void solve()
     41 {
     42     now=1,pre=0;
     43     tot[now]=1;
     44     hash[now][1]=0,f[now][1]=1;
     45     for (int i=1;i<=n;i++)
     46     {
     47         for (int j=1;j<=tot[now];j++)hash[now][j]<<=2;
     48         for (int j=1;j<=m;j++)
     49         {
     50             swap(now,pre),tot[now]=0;
     51             cnt=0;
     52             memset(f[now],0,sizeof(f[now]));
     53             memset(hed,0,sizeof(hed));
     54             for (int k=1;k<=tot[pre];k++)
     55             {
     56                 int sta=hash[pre][k],num=f[pre][k];
     57                 if(!num)continue;
     58                 int x=(sta/(1<<bit[j-1]))%4,y=(sta/(1<<bit[j]))%4;
     59                 if(!a[i][j])
     60                 {
     61                     if(!x&&!y)ins(sta,num);
     62                 }
     63                 else if(!x&&!y)
     64                 {
     65                     if(a[i+1][j])ins(sta+(1<<bit[j-1]),num);
     66                     if(a[i][j+1])ins(sta+(1<<bit[j]),num);
     67                     if(a[i+1][j]&&a[i][j+1])ins(sta+(1<<bit[j-1]+1)+(1<<(bit[j]+1)),num);
     68                 }
     69                 else if(!x)
     70                 {
     71                     if(y==1)
     72                     {
     73                         sta-=(1<<bit[j]);
     74                         if(a[i][j+1])ins(sta+(1<<bit[j]+1),num);
     75                         if(a[i+1][j])ins(sta+(1<<bit[j-1]),num);
     76                     }
     77                     else
     78                     {
     79                         sta-=(1<<bit[j]+1);
     80                         ins(sta,num);
     81                         if(a[i+1][j])ins(sta+(1<<bit[j-1]+1),num);
     82                     }
     83                 }
     84                 else if(!y)
     85                 {
     86                     if(x==1)
     87                     {
     88                         sta-=(1<<bit[j-1]);
     89                         if(a[i][j+1])ins(sta+(1<<bit[j]),num);
     90                         if(a[i+1][j])ins(sta+(1<<bit[j-1]+1),num);
     91                     }
     92                     else
     93                     {
     94                         sta-=(1<<bit[j-1]+1);
     95                         ins(sta,num);
     96                         if(a[i][j+1])ins(sta+(1<<bit[j]+1),num);
     97                     }
     98                 }
     99                 else if(x==1&&y==1)
    100                 {
    101                     sta-=(1<<bit[j-1])+(1<<bit[j]);
    102                     ins(sta,num);
    103                 }
    104             }
    105         }
    106     }
    107 }
    108 int main()
    109 {
    110     for (int i=0;i<=100;i++)bit[i]=i<<1;
    111     n=read(),m=read();
    112     if(n>=m)
    113     {
    114         for (int i=1;i<=n;i++)
    115         {
    116             scanf("%s",s+1);
    117             for (int j=1;j<=m;j++)
    118                 if(s[j]=='_')a[i][j]=1;
    119                 else a[i][j]=0;
    120         }
    121     }
    122     else
    123     {
    124         for (int i=1;i<=n;i++)
    125         {
    126             scanf("%s",s+1);
    127             for (int j=1;j<=m;j++)
    128                 if(s[j]=='_')a[j][i]=1;
    129                 else a[j][i]=0;
    130         }
    131         swap(n,m);
    132     }
    133     solve();
    134     printf("%d
    ",f[now][1]);
    135 }
  • 相关阅读:
    软件开发记录04
    《敏捷软件需求》阅读笔记02
    软件开发记录03
    《敏捷软件需求》阅读笔记01
    软件开发记录02
    Leetcode
    Leetcode
    Leetcode
    leetcode -625-Minimum Factorization
    51Nod
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8486733.html
Copyright © 2011-2022 走看看