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

      用四进制表示状态。

      用hash表把一个四进制数映射到一个小数上。

      这样就可以memset了。

      转移的时候分类讨论一下,特判下边界情况。

      

      1 #include<iostream>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<cstdio>
      5 #define bq 1<<bit[j]
      6 #define bp 1<<bit[j-1]
      7 using namespace std;
      8 int n,m;
      9 int map[105][105],bi[105][105];
     10 char s[105];
     11 const int maxn=200010;
     12 int f[2][maxn],tot[2],hash[2][maxn],head[maxn],ver[maxn],nxt[maxn],bit[110];
     13 int num,pre,now;
     14 const int mod = 20110520;
     15 void add(int s,int d)
     16 {
     17     int x=s%50000;
     18     for(int i=head[x];i;i=nxt[i])
     19     {
     20         if(hash[now][ver[i]]==s)
     21         {
     22             f[now][ver[i]]=(f[now][ver[i]]+d)%mod;
     23             return ;
     24         }
     25     }
     26     tot[now]++;
     27     hash[now][tot[now]]=s;
     28     f[now][tot[now]]=d;
     29     num++;ver[num]=tot[now];nxt[num]=head[x];head[x]=num;
     30     return ;
     31 }
     32 int main()
     33 {
     34     for(int i=1;i<=100;i++)bit[i]=i*2;
     35     scanf("%d%d",&n,&m);
     36     for(int i=1;i<=n;i++)
     37     {
     38         scanf("%s",s);
     39         for(int j=1;j<=m;j++)
     40         {
     41             if(s[j-1]=='*')map[i][j]=0;
     42             else map[i][j]=1;
     43         }
     44     }
     45     if(n<m)
     46     {
     47         for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)bi[j][i]=map[i][j]; 
     48         memset(map,0,sizeof(map));
     49         for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)map[j][i]=bi[j][i];
     50         swap(n,m);
     51     }
     52     now=1;pre=0;tot[now]=1;hash[now][1]=0;f[now][1]=1;
     53     for(int i=1;i<=n;i++)
     54     {
     55         for(int j=1;j<=tot[now];j++)hash[now][j]<<=2;
     56         for(int j=1;j<=m;j++)
     57         {
     58             now^=1;pre^=1;
     59                memset(head,0,sizeof(head));
     60                memset(f[now],0,sizeof(f[now]));
     61             tot[now]=0;num=0;
     62             for(int k=1;k<=tot[pre];k++)
     63             {
     64                 int s=hash[pre][k],num=f[pre][k];
     65                 if(!num)continue;
     66                 int p=(s/(bp))&3,q=(s/(bq))&3;
     67                 if(!map[i][j])
     68                 {
     69                     if(!p&&!q)add(s,num);
     70                 }
     71                 else if(!p&&!q)
     72                 {
     73                     add(s+(bp),num);
     74                     if(j<m)add(s|(bq),num),add(s|(bp+1)|(bq+1),num);
     75                 }
     76                 else if(!p)
     77                 {
     78                     if(q==1)
     79                     {
     80                         s^=(bq);
     81                         add(s|(bp),num);
     82                         if(j<m)add(s|(bq+1),num);
     83                     }
     84                     else
     85                     {
     86                         s^=(bq+1);
     87                         add(s|(bp+1),num);
     88                         add(s,num);
     89                     }
     90                 }
     91                 else if(!q)
     92                 {
     93                     if(p==1)
     94                     {
     95                         s^=(bp);
     96                         add(s|(bp+1),num);
     97                         if(j<m)add(s|(bq),num);
     98                     }
     99                     else
    100                     {
    101                         s^=(bp+1);
    102                         if(j<m)add(s|(bq+1),num);
    103                         add(s,num);
    104                     }
    105                 }
    106                 else if(p==1&&q==1)
    107                 {
    108                     add(s^(bq)^(bp),num);
    109                 }
    110             }   
    111         }
    112     }
    113     int ans=0;
    114     for(int i=head[0];i;i=nxt[i])
    115     {
    116         if(hash[now][ver[i]]==0)ans=f[now][ver[i]];
    117     }
    118     printf("%d
    ",ans);
    119     return 0;
    120 }
  • 相关阅读:
    django-缓存的应用
    Faster-RCNN用于场景文字检测训练测试过程记录(转)
    faster-rcnn在ubuntu16.04环境下的超级详细的配置(转)
    Effective C++读书笔记(转)
    c++中的static,const,const static以及它们的初始化
    [leetcode]Validate Binary Search Tree 验证二叉搜索树
    二叉树的遍历方式(迭代)
    c++中string与int之间的相互转换
    c++中 cin,cin.get(),cin.getline(),getline()用法说明
    N皇后问题代码
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6481623.html
Copyright © 2011-2022 走看看